Reputation: 13
in a university project my team and I have to build a scanning unit. After processing the scanning unit returns a Byte Array consisting of 8-bit grayscale values (approx 3,7k Pixels in the Heigth and 20k Pixels in the Width, this huge resolution is necessary, so setting PixelData Pixelwise is no option as this would take to much time).
While searching the internet i have found an answer in This SO topic. I tried it implementing as the following:
public static class Extensions
{
public static Image ImageFromArray(
this byte[] arr, int width, int height)
{
var output = new Bitmap(width, height, PixelFormat.Format16bppGrayScale);
var rect = new Rectangle(0, 0, width, height);
var bmpData = output.LockBits(rect,
ImageLockMode.ReadWrite, output.PixelFormat);
var ptr = bmpData.Scan0;
Marshal.Copy(arr, 0, ptr, arr.Length);
output.UnlockBits(bmpData);
return output;
}
}
I tried running the Function with an array filled like this:
testarray[0] = 200;
testarray[1] = 255;
testarray[2] = 90;
testarray[3] = 255;
testarray[4] = 0;
testarray[5] = 0;
testarray[6] = 100;
testarray[7] = 155;
And wanted to show the bmp in a picturebox with:
pictureBox1.Image = Extensions.ImageFromArray(testarray, 2, 2);
When debugging, the code runs trough the function, but the result is the Errorimage showing.
Also, if someone knows an easier method to compute the task, it would be very nice to share the way. I could not find a way to
Thank you very much for your help :)
Upvotes: 0
Views: 1414
Reputation: 1667
Use Format8bppIndexed and set the obvious palette
Bitmap ImageFromArray(byte[] arr, int width, int height)
{
var output = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
var rect = new Rectangle(0, 0, width, height);
var bmpData = output.LockBits(rect,ImageLockMode.WriteOnly, output.PixelFormat);
var ptr = bmpData.Scan0;
if (bmpData.Stride != width)
throw new InvalidOperationException("Cant copy directly if stride mismatches width, must copy line by line");
Marshal.Copy(arr, 0, ptr, width*height);
output.UnlockBits(bmpData);
var palEntries = new Color[256];
var cp = output.Palette;
for (int i = 0; i < 256; i++)
cp.Entries[i] = Color.FromArgb(i, i, i);
output.Palette = cp;
return output;
}
Set PictureBox.SizeMode to StretchImage. You'll probably need that.
Upvotes: 1