Question

I searched all question about byte array but i always failed. I have never coded c# i am new in this side. Could you help me how to make image file from byte array.

Here is my function which stores byte in array named imageData

public void imageReady( byte[] imageData, int fWidth, int fHeight))
Was it helpful?

Solution 2

Guys thank you for your help. I think all of this answers works. However i think my byte array contains raw bytes. That's why all of those solutions didnt work for my code.

However i found a solution. Maybe this solution helps other coders who have problem like mine.

static byte[] PadLines(byte[] bytes, int rows, int columns) {
   int currentStride = columns; // 3
   int newStride = columns;  // 4
   byte[] newBytes = new byte[newStride * rows];
   for (int i = 0; i < rows; i++)
       Buffer.BlockCopy(bytes, currentStride * i, newBytes, newStride * i, currentStride);
   return newBytes;
 }

 int columns = imageWidth;
 int rows = imageHeight;
 int stride = columns;
 byte[] newbytes = PadLines(imageData, rows, columns);

 Bitmap im = new Bitmap(columns, rows, stride, 
          PixelFormat.Format8bppIndexed, 
          Marshal.UnsafeAddrOfPinnedArrayElement(newbytes, 0));

 im.Save("C:\\Users\\musa\\Documents\\Hobby\\image21.bmp");

This solutions works for 8bit 256 bpp (Format8bppIndexed). If your image has another format you should change PixelFormat .

And there is a problem with colors right now. As soon as i solved this one i will edit my answer for other users.

*PS = I am not sure about stride value but for 8bit it should be equal to columns.

And also this function Works for me.. This function copies 8 bit greyscale image into a 32bit layout.

public void SaveBitmap(string fileName, int width, int height, byte[] imageData)
        {

            byte[] data = new byte[width * height * 4];

            int o = 0;

            for (int i = 0; i < width * height; i++)
            {
                byte value = imageData[i];


                data[o++] = value;
                data[o++] = value;
                data[o++] = value;
                data[o++] = 0; 
            }

            unsafe
            {
                fixed (byte* ptr = data)
                {

                    using (Bitmap image = new Bitmap(width, height, width * 4,
                                PixelFormat.Format32bppRgb, new IntPtr(ptr)))
                    {

                        image.Save(Path.ChangeExtension(fileName, ".jpg"));
                    }
                }
            }
        }

OTHER TIPS

You'll need to get those bytes into a MemoryStream:

Bitmap bmp;
using (var ms = new MemoryStream(imageData))
{
    bmp = new Bitmap(ms);
}

That uses the Bitmap(Stream stream) constructor overload.

UPDATE: keep in mind that according to the documentation, and the source code I've been reading through, an ArgumentException will be thrown on these conditions:

stream does not contain image data or is null.
-or-
stream contains a PNG image file with a single dimension greater than 65,535 pixels.

Can be as easy as:

var ms = new MemoryStream(imageData);
System.Drawing.Image image = Image.FromStream(ms);

image.Save("c:\\image.jpg");

Testing it out:

byte[] imageData;

// Create the byte array.
var originalImage = Image.FromFile(@"C:\original.jpg");
using (var ms = new MemoryStream())
{
    originalImage.Save(ms, ImageFormat.Jpeg);
    imageData = ms.ToArray();
}

// Convert back to image.
using (var ms = new MemoryStream(imageData))
{
    Image image = Image.FromStream(ms);
    image.Save(@"C:\newImage.jpg");
}

In addition, you can simply convert byte array to Bitmap.

var bmp = new Bitmap(new MemoryStream(imgByte));

You can also get Bitmap from file Path directly.

Bitmap bmp = new Bitmap(Image.FromFile(filePath));

This was helpful to me: https://www.tek-tips.com/viewthread.cfm?qid=1264492 (Reference answer)

I understand the question as follows:

  • I have a byte array that contains pixel data e.g. in RGB format (24bit/pixel)
  • From this raw pixel data I want to create a Bitmap

This code worked for me:

int width = ...;
int height = ...;
byte[] pixelArray = new byte[] {
  // Creation of the actual data is not in the scope of this answer
};

Bitmap bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppRgb);

// Create a BitmapData and lock all pixels to be written 
BitmapData bmpData = bmp.LockBits(
                    new Rectangle(0, 0, bmp.Width, bmp.Height),
                    ImageLockMode.WriteOnly, bmp.PixelFormat);
// Copy the data from the byte array into BitmapData.Scan0
Marshal.Copy(pixelArray, 0, bmpData.Scan0, pixelArray.Length);

// Unlock the pixels
bmp.UnlockBits(bmpData);

// Do something with your image, e.g. save it to disc
bmp.Save("c:\\temp\\mybmp.bmp", ImageFormat.Bmp);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top