I'm using this code to save a bitmap as binary data.
Bitmap bmp = new Bitmap(screenWidth, position);
Graphics g = Graphics.FromImage(bmp);
g.CopyFromScreen(screenLeft, screenTop, 0, 0, bmp.Size);
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat);
IntPtr ptr = bmpData.Scan0;
int bytes = bmpData.Stride * bmp.Height;
byte[] rgbValues = new byte[bytes];
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
bmp.UnlockBits(bmpData);
File.WriteAllBytes(filename, bmp);
g.Dispose();
As I only need the first channel's values, is it possible to retrieve that from the bitmap? Performance is essential.
You're almost there, but there are a few key details missing:
bmp.PixelFormat, force the pixel format for theBitmapDataobject toPixelFormat.Format32BppArgb, then you're 100% sure what structure you will get, and in 32-bit mode, the stride will always exactly match a predictablewidth * 4. If you don't do this, you may get unexpected results if the read image happens to be paletted or some sort of 16bpp format where each pixel can't be divided into simple colour component bytes.Uint32value, meaning the actual order of the colour component bytes is the reverse:{ BB, GG, RR, AA }.So, to extract your channel:
This just saves the data as byte array. If you want to write it as image, the simplest way is probably to make an 8-bit bitmap, open a BitmapData object on it, and write the lines into it one by one, and then set its colour palette to a generated range from 0,0,0 to 255,255,255.
I posted a function that takes a byte array, image dimensions and a palette and makes an image out of it in this answer.