1

I am using barcode device with OPOS DirectIO commands to switch between modes.

the problem is when i use the device to capture image i get a byte array

(from the device specifications the image i get is "752x480 GrayScale 256,16,2" in JPG format) and i couldn't find a way to convert it to (Image).

I've tried below code

MemoryStream ms = new MemoryStream(scannedByteArray);
pictureBox1.Image = Image.FromStream(ms);

but it didn't work. always throwing "Parameter is not valid" Exception.

Also tried this:

            byte[] buffer = scannedByteArray;
            var bitmap = new Bitmap(752, 480, PixelFormat.Format24bppRgb);
            var bitmap_data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
            Marshal.Copy(buffer, 0, bitmap_data.Scan0, buffer.Length);
            bitmap.UnlockBits(bitmap_data);

and an alternative way with stride :

Bitmap im = new Bitmap(752, 480, -752,
                     PixelFormat.Format8bppIndexed,
                     Marshal.UnsafeAddrOfPinnedArrayElement(scannedByteArray, 0));

and i was getting bad image or corrupted image with wrong colors.

i tried so many solutions (as below ones) but none of them helped

1st: Byte Array to Image Conversion

2nd: How to convert image to byte array (here i was trying to do the opposite solution and it didn't work) I've been spending 3 days on this problem and still no idea how i can display the image or save it.

Note 1: the byte array size is variable (not fixed every time i capture the image i get a different size of byte array)

Note 2: I've tried pixel formats as 24 bits, 16 bits and 8 bits with different values of stride and always get bad or corrupted image displayed.

UPDATE:

I tried to use JpegBitmapDecoder as follow:

 JpegBitmapDecoder decoder = new JpegBitmapDecoder(ms, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
            BitmapSource bitmapsource = decoder.Frames[0];
            Bitmap bitmap = new Bitmap(bitmapsource.PixelWidth, bitmapsource.PixelHeight);
            Rectangle rec = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
            BitmapData bitmapdata = bitmap.LockBits(rec, ImageLockMode.WriteOnly,
                (bitmapsource.Format.BitsPerPixel == 24 ? System.Drawing.Imaging.PixelFormat.Format24bppRgb : System.Drawing.Imaging.PixelFormat.Format32bppArgb));
            bitmapsource.CopyPixels(System.Windows.Int32Rect.Empty, bitmapdata.Scan0, bitmapdata.Height * bitmapdata.Stride, bitmapdata.Stride);
            bitmap.UnlockBits(bitmapdata);

but the Error "No imaging component suitable to complete this operation" appeared at the first line and i am sure the bytes i receive from the device is not corrupted because the device works on its demo without any problems and without any changes in its configurations.

UPDATE 2:

here is sample of bytes i get from the device when capturing image.

https://drive.google.com/file/d/1kBuLDMTe9snwin9voEJ7z6kr9QKizftf/view?usp=sharing

Mazen Ak
  • 152
  • 7
  • What is the exception for this code ? MemoryStream ms = new MemoryStream(scannedByteArray); pictureBox1.Image = Image.FromStream(ms); This seems to be the right solution. – farbiondriven Dec 10 '18 at 15:41
  • that's the point, all of solutions seem to be right. but i always get something wrong. here i get "parameter is not valid" exception. @farbiondriven – Mazen Ak Dec 10 '18 at 16:40
  • For what I know, GDI+ doesn't support 16bit GrayScale images. `System.Windows.Media` does (`PixelFormats.Gray16`). It can be converted to a `BitmapSource` (or a `System.Drawing.Bitmap`) using the [JpegBitmapDecoder](https://learn.microsoft.com/en-us/dotnet/api/system.windows.media.imaging.jpegbitmapdecoder). You can also try to converto it to a GDI+ Bitmap using the `Format16bppGrayScale` format, but I'm not really sure it's the right one. If you can share the byte array (in raw/binary format...) – Jimi Dec 10 '18 at 16:54
  • I've tried the `Format16bppGrayScale` but also not worked. the image was showing as big red 'X' in the picture box. i will try the Decoder and update the question with the result i will get. @Jimi – Mazen Ak Dec 10 '18 at 17:04
  • @Jimi, I've tried your suggestion. now i get "No imaging component suitable to complete this operation" and after some googling some people say this error related to corrupted image stream. for note: i have a demo for the device without any source code and it works. i can capture images and save them in jpg format with no errors and without any change on device configurations. – Mazen Ak Dec 10 '18 at 17:55
  • Well, can you `File.WriteAllBytes` that array of *things* and share it? Btw, you didn't say where you get the error on your last try and your `BitmapSource` should be `BitmapSource bitmapsource = (BitmapSource)bitmapDecoder.Frames[0].GetAsFrozen();` – Jimi Dec 10 '18 at 18:07
  • If you save your array as bytes on disk (`File.WriteAllBytes([path]`)) you won't have any error because no specific format is requested (you could also try to open the file with a graphics program). If you can share that blob of bytes, posting it somewhere, I can give it a look and, possibly, tell you what's what. – Jimi Dec 11 '18 at 11:47
  • @Jimi i got the error at the first line (JpegBitmapDecoder declaration line) as i mentioned in the question update above and here you can find the byte array i got from the device. https://drive.google.com/file/d/1kBuLDMTe9snwin9voEJ7z6kr9QKizftf/view?usp=sharing – Mazen Ak Dec 11 '18 at 11:47
  • 1
    That file is a partial JFIF (jpeg) file. The header has been modified: the file format signature is partial (the first 3 bytes have been changed). The file termination signature is missing. The internal table has been stripped/modified. It apperas to be intentional. It's common practice to produce a standard file format and then tamper with the generated file to obtain a *proprietary* format. Of course it could also be corrupted. I doubt it but I have seen just one *sample* so... – Jimi Dec 11 '18 at 13:17
  • i never thought it could be complicated like that. i am sorry i don't have enough experience to deal with such cases would you please tell me what to do in order to make this bytes visible as image ? if that could help i can provide more samples of bytes. @Jimi – Mazen Ak Dec 11 '18 at 15:37
  • See this SO answer: [The JPEG/JFIF format](https://stackoverflow.com/a/27310261/7444103) – Jimi Dec 13 '18 at 09:44

1 Answers1

0

Can you try this ?

pictureBox1.Image = Image x = (Bitmap)((new ImageConverter()).ConvertFrom(scannedByteArray));
farbiondriven
  • 2,450
  • 2
  • 15
  • 31