/// <summary> /// Highly optimized function that iterates through bitmap pixels with simplicity and supports breaking in the middle of looping. /// Can most likely be optimized even more with while loop instead of two for loops. /// </summary> /// <param name="bitmap"></param> /// <param name="pixelCallback"></param> unsafe public void ForeachPixelCheckBreak(Bitmap bitmap, PixelIterationCallbackCheckBreak pixelCallback) { BitmapData bmpData = bitmap.LockBits(new Rectangle(Point.Empty, bitmap.Size), ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb); byte *pBeg = (byte *)bmpData.Scan0.ToPointer(); bool shouldBreak = false; for (int y = 0; y < bmpData.Height; ++y) { for (int x = 0; x < bmpData.Width; ++x) { if (!pixelCallback(x, y, (Pixel *)pBeg)) { shouldBreak = true; break; } pBeg += sizeof(Pixel); } if (shouldBreak) { break; } } bitmap.UnlockBits(bmpData); }
unsafe public void ForeachPixelCheckBreak(Bitmap bitmap, PixelIterationCallbackCheckBreak pixelCallback) { BitmapData bmpData = bitmap.LockBits(new Rectangle(Point.Empty, bitmap.Size), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); byte *pBeg = (byte *)bmpData.Scan0.ToPointer(); bool shouldBreak = false; for (int y = 0; y < bmpData.Height; ++y) { for (int x = 0; x < bmpData.Width; ++x) { // 24 / 8 is dependant on the pixelformat byte *data = pBeg + y * bmpData.Stride + x * 32 / 8; if (!pixelCallback(x, y, (Pixel *)data)) { shouldBreak = true; break; } } if (shouldBreak) { break; } } bitmap.UnlockBits(bmpData); }