How to Convert Image File Data in a Byte Array to a Bitmap

How to convert image file data in a byte array to a Bitmap?

Just try this:

Bitmap bitmap = BitmapFactory.decodeFile("/path/images/image.jpg");
ByteArrayOutputStream blob = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.PNG, 0 /* Ignored for PNGs */, blob);
byte[] bitmapdata = blob.toByteArray();

If bitmapdata is the byte array then getting Bitmap is done like this:

Bitmap bitmap = BitmapFactory.decodeByteArray(bitmapdata, 0, bitmapdata.length);

Returns the decoded Bitmap, or null if the image could not be decoded.

How to create bitmap from byte array?

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"));
}
}
}
}

Create a bitmap from a stored byte array and save to disk throws GDI+ exception when source of byte array was a jpg

You're disposing the MemoryStream before the image is written, try disposing the stream after the file has been saved. That worked for me :)

If you want to get the image format, try detecting it from the first few bytes of the stream:

Wikipedia: file-signature-list

Show an array of bytes as an image on a form

The Bitmap(Stream, bool) constructor expects a stream with an actual image format (eg. PNG, GIF, etc.) along with header, palette, and possibly compressed image data.

To create a Bitmap from raw data, you need to use the Bitmap(int width, int height, int stride, PixelFormat format, IntPtr scan0) constructor, but that is also quite inconvenient because you need a pinned raw data that you can pass as scan0.

The best if you just create an 8bpp bitmap with grayscale palette and set the pixels manually:

var bmp = new Bitmap(256, 256, PixelFormat.Format8bppIndexed);

// making it grayscale
var palette = bmp.Palette;
for (int i = 0; i < 255; i++)
palette.Entries[i] = Color.FromArgb(i, i, i);
bmp.Palette = palette;

Now you can access its raw content as bytes where 0 is black and 255 is white:

var bitmapData = bmp.LockBits(new Rectangle(Point.Empty, bmp.Size), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
for (int y = 0; y < bitmapData.Height; y++)
{
for (int x = 0; x < bitmapData.Width; x++)
{
unsafe
{
((byte*) bitmapData.Scan0)[y * bitmapData.Stride + x] = (byte)x;
}
}
}
bmp.UnlockBits(bitmapData);

The result image:
8bpp indexed grayscale image with horizontal gradient

But if you don't want to use unsafe code, or you want to set pixels by colors, you can use this library (disclaimer: written by me) that supports efficient manipulation regardless of the actual PixelFormat. Using that library the last block can be rewritten like this:

using (IWritableBitmapData bitmapData = bmp.GetWritableBitmapData())
{
IWritableBitmapDataRow row = bitmapData.FirstRow;
do
{
for (int x = 0; x < bitmapData.Width; x++)
row[x] = Color32.FromGray((byte)x); // this works for any pixel format
// row.SetColorIndex(x, x); // for the grayscale 8bpp bitmap created above
} while (row.MoveNextRow());
}

Or like this, using Parallel.For (this works only because in your example all rows are the same so the image is a horizontal gradient):

using (IWritableBitmapData bitmapData = bmp.GetWritableBitmapData())
{
Parallel.For(0, bitmapData.Height, y =>
{
var row = bitmapData[y];
for (int x = 0; x < bitmapData.Width; x++)
row[x] = Color32.FromGray((byte)x); // this works for any pixel format
// row.SetColorIndex(x, x); // for the grayscale 8bpp bitmap created above
});
}

How can I convert a .bmp file into an array of 1s and 0s in C#?

Try following :

            byte[] input = {0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF,
0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x03,
0x00, 0x00, 0x00, 0x0F,
0xFF, 0xFF, 0xFF, 0xFF,
0xF0, 0x00, 0x00, 0x00,
0xE0, 0x00, 0x00, 0x00,
0xC0, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF
};
string[] doubleWords = input.Select((x,i) => new {b = x, index = i})
.GroupBy(x => x.index/4)
.Select(x => string.Join("",x.Select(y => Convert.ToString(y.b, 2).PadLeft(8,'0'))))
.ToArray();


Related Topics



Leave a reply



Submit