0

I have been trying to get a simple byte array in to a Picture box using c#. Most examples I tried give me parameter invalid. If I don't use a using or converter and break it out like so (see code below) I do get an image but it looks wrong (all black with some random colored dots up top).

 Bitmap bmp = new Bitmap(48, 32, PixelFormat.Format24bppRgb);
            BitmapData bmpData = bmp.LockBits(
                                 new Rectangle(0, 0, bmp.Width, bmp.Height),
                                 ImageLockMode.WriteOnly, bmp.PixelFormat);
            Marshal.Copy(blob, 0, bmpData.Scan0, blob.Length);
            bmp.UnlockBits(bmpData);
            return bmp;

The byte array looks like this.

01 c7 f0 70 3f 03 00 c3 f0 60 1e 01 80 63 ff c3 1c 71 88 21 ff c7 3c f3 8e 31 f0 c7 fc ff 86 31 f0 c7 fc ff c4 31 f0 c1 fc 3f c0 31 e0 e0 7e 0f c0 f1 e1 f8 3f 83 c0 31 e1 fe 1f e1 c6 31 e0 ff 9f f9 86 30 f0 fb 9c 79 8f 38 f0 e3 98 79 8f 38 f8 63 98 79 80 30 38 62 1c 61 80 70 10 70 3e 03 ff ff ff ff ff ff ff ff ff ff ff ff 00 7e 00 78 7f f0 88 3c 18 18 3f f0 8e 3c 7e 0f 0f c3 86 30 ff 07 87 87 c4 31 ff 87 e0 8f c0 71 ff e7 f8 0f c0 71 ff e7 f0 0f c0 71 ff e7 f0 0f c6 71 ff e7 f0 1f 86 10 ff 87 e1 1f 8f 18 ff 8f 87 87 8f 18 7f 0f 0f c3 80 1c 0c 18 3f f0 80 7e 00 38 7f f0

My image should be 192 bytes and a 48 x 32 res image. What am I doing wrong?

8
  • 48 x 32 = 1536 pixels. 192 bytes x 8 bits/byte = 1536 bits. You have just 1 bit per pixel, so this is a monochrome bitmap, and Format24bppRgb (24 bits per pixel) is wrong. Commented May 17, 2018 at 3:51
  • Calculate the space one pixel can take, from the number of bytes and the number of pixels. Then find the correct pixel format from the doc. Commented May 17, 2018 at 3:51
  • Can you post what the image should look like? Commented May 17, 2018 at 9:00
  • Michael I only have Format16bppGrayScale and that gives me a red box with a square. I dont see a monochrome. Commented May 17, 2018 at 22:40
  • Here is the image in characters using a byte to text function.pastebin.com/7qKgFksK Commented May 17, 2018 at 22:43

1 Answer 1

1

As Michael Liu commented, if your data is 192 bytes, and you need to get 32 lines of data out of that, then each line will be 6 bytes, meaning that to get 48 pixels out of such a line, you need to multiply it by 8, or, in other words, use 1 bit per pixel, which is PixelFormat.Format1bppIndexed.

As for your problems in visualizing the data, you need to take the stride into account; the actual amount of bytes per line of pixels.

Images created by the .Net framework always use a multiple of four bytes as width of each line of pixels, so the new 48x32 image you make will have 8 bytes on each line. However, your image data is completely compact data, so it only has 6 bytes per line.

So you need to copy it line by line, keeping the stride of both your input and output into account. This means you should replace the single Marshal.Copy by a loop over the height that does one Marshal.Copy per line, copying the data per 6 bytes from the input array to the correct start pointer of each line on the output.

The adjusted Marshal.Copy operation should be something like this:

Int32 newDataWidth = ((Image.GetPixelFormatSize(pixelFormat) * width) + 7) / 8;
Int32 targetStride = bmpData.Stride;
Int64 scan0 = bmpData.Scan0.ToInt64();
for (Int32 y = 0; y < height; y++)
    Marshal.Copy(blob, y * stride, new IntPtr(scan0 + y * targetStride), newDataWidth);

...with stride the stride of your input array (so in this case, 6).

To automate the input stride calculation, if you know you have completely compact data, you can use the formula I already kind of showed in the previous block:

public static Int32 GetMinimumStride(Int32 width, Int32 bitsLength)
{
    return ((bitsLength * width) + 7) / 8;
}

I already posted code here on SO to build an image from bytes in any format, so you can just use that, I guess. Using that BuildImage function, you can build your image like this:

public static Bitmap BuildMonoBitmap(Byte monoBytes, Int32 width, Int32 height)
{
    Color[] pal = new Color[] {Color.Black, Color.White};
    Int32 stride = GetMinimumStride(width, 1);
    return BuildImage(monoBytes, width, height, stride, PixelFormat.Format1bppIndexed, pal, null);
}

The result, shown in my test program:

Bliss Box

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.