Skip to content

Instantly share code, notes, and snippets.

@GMMan
Created November 20, 2014 02:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GMMan/163823f663f99f21fd96 to your computer and use it in GitHub Desktop.
Save GMMan/163823f663f99f21fd96 to your computer and use it in GitHub Desktop.
Get consecutive scanlines in a Bitmap using foreach
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
class BitmapScanlineEnumerable : IEnumerable<IntPtr>
{
BitmapData bmd;
public bool VerticalFlip { get; set; }
public BitmapScanlineEnumerable(BitmapData bmd, bool verticalFlip)
{
this.bmd = bmd;
VerticalFlip = verticalFlip;
}
public IEnumerator<IntPtr> GetEnumerator()
{
IntPtr scan = bmd.Scan0;
if (VerticalFlip) scan += (bmd.Height - 1) * bmd.Stride;
for (int i = 0; i < bmd.Height; ++i)
{
yield return scan;
if (!VerticalFlip) scan += bmd.Stride;
else scan -= bmd.Stride;
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
@GMMan
Copy link
Author

GMMan commented Nov 20, 2014

Why? Because trying to calculate scanline addresses inside of loops is annoying, plus what if your source image has scanlines that run from top to bottom instead of bottom to top? Using this code, just focus on getting each row of pixels copied.

Sample usage:

static Bitmap GetBitmapFromRawArgb8888(byte[] data, int width, int height, bool vertFlip)
{
    Bitmap bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
    BitmapData lockedBits = bmp.LockBits(new Rectangle(Point.Empty, bmp.Size), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
    unsafe
    {
        int dataIndex = 0;
        foreach (IntPtr scan in new BitmapScanlineEnumerable(lockedBits, vertFlip))
        {
            for (int i = 0; i < width * 4; ++i)
            {
                ((byte*)scan)[i] = data[dataIndex++];
            }
        }
    }
    bmp.UnlockBits(lockedBits);
    return bmp;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment