111,092
社区成员




private void Desaturate(Bitmap Bmp)
{
if (Bmp.PixelFormat == PixelFormat.Format24bppRgb)
{
BitmapData BmpData = Bmp.LockBits(new Rectangle(0, 0, Bmp.Width, Bmp.Height), ImageLockMode.ReadOnly, Bmp.PixelFormat);
Parallel.ForEach(Partitioner.Create(0, BmpData.Height), (H) =>
{
int X, Y, Width, Height, Stride;
byte Red, Green, Blue, Max, Min, Value;
byte* Scan0, CurP;
Width = BmpData.Width; Height = BmpData.Height; Stride = BmpData.Stride; Scan0 = (byte*)BmpData.Scan0;
for (Y = H.Item1; Y < H.Item2; Y++)
{
CurP = Scan0 + Y * Stride;
for (X = 0; X < Width; X++)
{
Blue = *CurP; Green = *(CurP + 1); Red = *(CurP + 2);
if (Blue > Green)
{
Max = Blue;
Min = Green;
}
else
{
Max = Green;
Min = Blue;
}
if (Red > Max)
Max = Red;
else if (Red < Min)
Min = Red;
Value = (byte)((Max + Min) >> 1);
*CurP = Value; *(CurP + 1) = Value; *(CurP + 2) = Value;
CurP += 3;
}
}
});
Bmp.UnlockBits(BmpData);
}
public static void ZoomBlur(Bitmap Bmp, int SampleRadius = 100, int Amount = 100, int CenterX = 256, int CenterY = 256)
{
int Width, Height, Stride;
BitmapData BmpData = Bmp.LockBits(new Rectangle(0, 0, Bmp.Width, Bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
Width = BmpData.Width; Height = BmpData.Height; Stride = BmpData.Stride;
byte* BitmapClone = (byte*)Marshal.AllocHGlobal(BmpData.Stride * BmpData.Height);
CopyMemory(BitmapClone, BmpData.Scan0, BmpData.Stride * BmpData.Height);
Parallel.ForEach(Partitioner.Create(0, Height, Height / Environment.ProcessorCount), (H) =>
{
int SumRed, SumGreen, SumBlue,Fx, Fy, Fcx, Fcy;
int X, Y, I;
byte* Pointer, PointerC;
uint* Row, RowP;
Fcx = CenterX << 16 + 32768;
Fcy = CenterY << 16 + 32768;
Row = (uint*)Marshal.AllocHGlobal(SampleRadius * 4);
for (Y = H.Item1; Y < H.Item2; Y++)
{
Pointer = (byte*)BmpData.Scan0 + Stride * Y;
Fy = (Y << 16) - Fcy;
RowP = Row;
for (I = 0; I < SampleRadius; I++)
{
Fy -= ((Fy >> 4) * Amount) >> 10;
*RowP = (uint)(BitmapClone + Stride * ((Fy + Fcy) >> 16));
RowP++;
}
for (X = 0; X < Width; X++)
{
Fx = (X << 16) - Fcx;
SumRed = 0; SumGreen = 0; SumBlue = 0;
RowP = Row;
for (I = 0; I < SampleRadius; I++)
{
Fx -= ((Fx >> 4) * Amount) >> 10;
PointerC = (byte*)*RowP + ((Fx + Fcx) >> 16) * 3; // *3不需要优化,编译器会变为lea eax,[eax+eax*2]
SumBlue += *(PointerC);
SumGreen += *(PointerC + 1);
SumRed += *(PointerC + 2);
RowP++;
}
*(Pointer) = (byte)(SumBlue / SampleRadius);
*(Pointer + 1) = (byte)(SumGreen / SampleRadius);
*(Pointer + 2) = (byte)(SumRed / SampleRadius);
Pointer += 3;
}
}
Marshal.FreeHGlobal((IntPtr)Row);
});
Marshal.FreeHGlobal((IntPtr)BitmapClone); // 释放掉备份数据
Bmp.UnlockBits(BmpData);
}
哈哈,顶一个~~~他老是一副说教的样子,很烦 [quote=引用 42 楼 youaway 的回复:] 看见SP1234在这里自说自话就烦。
LZ使用的并行方法,不是多线程 正如有人所说,并行可以说是GPU的天下,若是想把图像处理效率有数量级的提高, GPU则是很好的武器 NVIDIA的的CUDA可以看下, 以前做医疗影像的时候,算法部的同事,将灌注的同一算法移植到GPU上,效率提高了5倍,而且还是在没有怎么优化的情况下