// Based on http://stackoverflow.com/a/4748383/3813189 private static DataRectangle <RGB> GetRGB(this Bitmap image, int startX, int startY, int w, int h) { if (image == null) { throw new ArgumentNullException(nameof(image)); } if (startX < 0 || startX + w > image.Width) { throw new ArgumentOutOfRangeException(nameof(startX)); } if (startY < 0 || startY + h > image.Height) { throw new ArgumentOutOfRangeException(nameof(startY)); } if ((w <= 0) || (w > image.Width)) { throw new ArgumentOutOfRangeException(nameof(w)); } if ((h <= 0) || (h > image.Height)) { throw new ArgumentOutOfRangeException(nameof(h)); } var values = new RGB[w, h]; var data = image.LockBits(new Rectangle(startX, startY, w, h), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); try { var pixelData = new Byte[data.Stride]; for (var lineIndex = 0; lineIndex < data.Height; lineIndex++) { Marshal.Copy( source: data.Scan0 + (lineIndex * data.Stride), destination: pixelData, startIndex: 0, length: data.Stride ); for (var pixelOffsetWithinLine = 0; pixelOffsetWithinLine < data.Width; pixelOffsetWithinLine++) { // Note: PixelFormat.Format32bppRgb means the data is stored in memory as BGR (note: we're using Format24bppRgb but the same applies) const int PixelWidth = 3; values[pixelOffsetWithinLine, lineIndex] = new RGB( pixelData[pixelOffsetWithinLine * PixelWidth + 2], pixelData[pixelOffsetWithinLine * PixelWidth + 1], pixelData[pixelOffsetWithinLine * PixelWidth] ); } } } finally { image.UnlockBits(data); } return(DataRectangle.For(values)); }
public static DataRectangle <RGB> GetRGB(this Bitmap image) { if (image == null) { throw new ArgumentNullException(nameof(image)); } var imageColours = image.GetColourData(); var values = new RGB[image.Width, image.Height]; for (var x = 0; x < image.Width; x++) { for (var y = 0; y < image.Height; y++) { var imageColour = imageColours[x, y]; values[x, y] = new RGB(imageColour.R, imageColour.G, imageColour.B); } } return(DataRectangle.For(values)); }