-1

I am trying to convert an object to an image.

I grab the object from a usb3 camera using the following:

object RawData = axActiveUSB1.GetImageWindow(0,0,608,608);

This returns a Variant (SAFEARRAY)

After reviewing further, RawData = {byte[1824, 608]}. The image is 608 x 608 so I'm guessing 1824 is 3 times the size due to the RGB component of the image. The camera's pixel format is BayerRGB8 and according to the API I am using the data type is represented in Bytes:

Camera Pixel Format | Output Format | Data type | Dimensions
Bayer8 | 24-bit RGB | Byte | 0 to SizeX * 3 - 1, 0 to Lines - 1

I can convert it to a bytes array using this code found at Convert any object to a byte[]

private byte[] ObjectToByteArray(Object obj)
        {
            if (obj == null)
                return null;
            BinaryFormatter bf = new BinaryFormatter();
            MemoryStream ms = new MemoryStream();
            bf.Serialize(ms, obj);
            return ms.ToArray();

        }

From here, I then do: (all of this code also found or derived from info on stack)

// convert object to bytes
byte[] imgasbytes = ObjectToByteArray(RawData);
// create a bitmap and put data in it to go into the picturebox
var bitmap = new Bitmap(608, 608, PixelFormat.Format24bppRgb);
var bitmap_data = bitmap.LockBits(new Rectangle(0, 0,bitmap.Width, bitmap.Height), ImageLockMode.WriteOnly, bitmap.PixelFormat);

Marshal.Copy(imgasbytes, 0, bitmap_data.Scan0, imgasbytes.Length );
bitmap.UnlockBits(bitmap_data);
var result = bitmap as Image; // this line not even really necessary
PictureBox.Image = result;

The code works, but I should see this: enter image description here

But I see this: enter image description here

I've done this in Python and had similar issues which I was able to resolve, but I'm not as strong in c# and am unable to progress from here. I need to rotate my image 90 degrees, but also I think that my issue relates to incorrectly converting the array. I think that I need to convert my object (SAFEARRAY) to a multidimensional array so that the RGB sits on top of one another. I have looked at many examples on how to do this, but I do not understand how to go about it.

Any feedback is greatly appreciated on what I am doing wrong.

EDIT I'm looking at this -> Convert RGB8 byte[] to Bitmap

which may be related to my issue.

IamSierraCharlie
  • 504
  • 5
  • 10

1 Answers1

0

It looks like the issue was exactly as I described. In the end, the main issue was that the array needed to be rotated. I found a solution here -> Rotate M*N Matrix (90 degrees)

When I rotated the image, It resolved the picture issue that I was seeing above. While my image is inverted now, I understand the issue and as a result, am not seeing the problem any more.

Here is the code in case anyone runs into the same issue

        byte[,] newImageAsBytes = new byte[ImageAsBytes.GetLength(1), ImageAsBytes.GetLength(0)];
        int newColumn, newRow = 0;
        for (int oldColumn = ImageAsBytes.GetLength(1) - 1; oldColumn >= 0; oldColumn--)
        {
            newColumn = 0;
            for (int oldRow = 0; oldRow < ImageAsBytes.GetLength(0); oldRow++)
            {
                newImageAsBytes[newRow, newColumn] = ImageAsBytes[oldRow, oldColumn];
                newColumn++;
            }
            newRow++;
        }
        byte[] b = ObjectToByteArray(newImageAsBytes);
        var bitmap = new Bitmap(608, 608, PixelFormat.Format24bppRgb); // 608 is my image size and I am working with a camera that uses BayerRGB8
        var bitmap_data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.WriteOnly, bitmap.PixelFormat);
        Marshal.Copy(b, 0, bitmap_data.Scan0, b.Length);
        bitmap.UnlockBits(bitmap_data);
        var result = bitmap as Image; // this line not even really necessary
        PictureBox.Image = result;
IamSierraCharlie
  • 504
  • 5
  • 10