Bitmap.GetPixel/SetPixel 效能極差。BitmapData 配合 LockBits 可直接存取記憶體,適合大量像素運算。
int h = bmp.Height, w = bmp.Width;
Bitmap bmpOut = new Bitmap(w, h, PixelFormat.Format24bppRgb);
BitmapData dataIn = bmp.LockBits(new Rectangle(0,0,w,h), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
BitmapData dataOut = bmpOut.LockBits(new Rectangle(0,0,w,h), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
unsafe
{
byte* pIn = (byte*)dataIn.Scan0.ToPointer();
byte* pOut = (byte*)dataOut.Scan0.ToPointer();
for (int y = 0; y < dataIn.Height; y++)
{
for (int x = 0; x < dataIn.Width; x++)
{
pOut[0] = (byte)(255 - pIn[0]); // B
pOut[1] = (byte)(255 - pIn[1]); // G
pOut[2] = (byte)(255 - pIn[2]); // R
pIn += 3; pOut += 3;
}
pIn += dataIn.Stride - dataIn.Width * 3;
pOut += dataOut.Stride - dataOut.Width * 3;
}
}
bmpOut.UnlockBits(dataOut);
bmp.UnlockBits(dataIn);
Scan0 |------------------ Stride ------------------| |---------- Width (pixels) ----------| B G R B G R B G R B G R B G R X X <- 第 1 列 B G R B G R B G R B G R B G R X X <- 第 2 列 ...
UnlockBits 釋放鎖定。