简体   繁体   中英

Got Reversed Image from Byte Array when converting to Base64

I need to get the raw bitmap data only (no header, or other information). I used the following code to get the bitmap data:

using (Bitmap bitmap = svgDocument.Draw())
{
  Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
  BitmapData bitmapData = bitmap.LockBits(rect, ImageLockMode.ReadWrite, bitmap.PixelFormat);
  var length = Math.Abs(bitmapData.Stride) * bitmapData.Height;

  byte[] bytes = new byte[length];
  Marshal.Copy(bitmapData.Scan0, bytes, 0, length);
  bitmap.UnlockBits(bitmapData);

  MemoryStream memoryStream = new MemoryStream();
  string filename = DateTime.Now.Ticks.ToString() + ".bmp"; // this works fine
  bitmap.Save(filename, ImageFormat.Bmp);

  string base64 = Convert.ToBase64String(bytes, Base64FormattingOptions.InsertLineBreaks); // the base64 is reversed. 
}

When I save the bitmap, everything looks fine. The image is not reversed. However when I use the bytes only to convert the data to Base64, then the image is reversed.

Edit 1:

I think this has nothing to do with the Base64 conversion. It seems that the bytes are in reversed order.

When I save the image using the code, the image looks like this:

在此处输入图片说明

When I use the bytes, then I see this:

在此处输入图片说明

Solution:

I found the solution. Instead of creating a new bitmap, I just skipped the first 54 bytes of header information and then stored the byte array.

MemoryStream memoryStream = new MemoryStream();
bitmap.Save(memoryStream, ImageFormat.Bmp);

// Skip header
IEnumerable<byte> bytes = memoryStream.ToArray().Skip(54);

The standard BMP format allows to store bytes of the image either in classical top/down order or in reverse order.

The way to tell whether your image is stored this way is to check the value of the Height parameter in the BMP header:

  • If Height < 0 , then the height of your image is abs(Height) and the pixels are stored in reverse (bottom / top) order.

  • If Height > 0 , then you are in the case you expect, where pixels are in 'normal' order, top to bottom.

I would say that what happens in your case is that you are starting from an image stored with a negative Height header (the SVG object must do that for some reason). But you do not check it, so you store the pixels in bottom to top order.

When you store with the BMP object, it figures that out for you from the context. But when you export just the pixels, then the third party application that loads your image sees positive Height and thus shows your image upside down.

You can find details about this pixel ordering in the Wikipedia page for BMP file format .

Edit:

So, when you write a BMP file to your disk, you have to do the following:

  1. Check whether your bytes are in top to bottom order (a) or in bottom to top order (b)

  2. If (a): put the height of your image as a positive value in the BMP header

  3. If (b): put - height as a negative value in the BMP header. So that the third party program that shows your image knows that it's reversed.

I found the solution. Instead of creating a new bitmap, I just skipped the first 54 bytes of header information and then stored the byte array.

MemoryStream memoryStream = new MemoryStream();
bitmap.Save(memoryStream, ImageFormat.Bmp);

// Skip header
IEnumerable<byte> bytes = memoryStream.ToArray().Skip(54);

I ran into the same problem but still needed a base 64 string (for HTML5 canvas). So I used the Image class to rotate the image, stored in a new stream, then convert to base64 string.

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

//Rotate and save to new stream
image.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);
MemoryStream streamOut = new MemoryStream();
image.Save(streamOut, System.Drawing.Imaging.ImageFormat.Jpeg);

//Convert to base64 string
string base64String = Convert.ToBase64String(streamOut.ToArray());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM