我只需要获取原始位图数据(没有标题或其他信息)。我使用以下代码获取位图数据:
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.
}
当我保存位图时,一切看起来都很好。图像不反转。但是,当我仅使用字节将数据转换为Base64时,图像将反转。
编辑1:
我认为这与Base64转换无关。字节似乎是相反的顺序。
当我使用代码保存图像时,图像看起来像这样:
当我使用字节时,我看到以下内容:
<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS93UjhHdC5wbmcifQ==” alt =“在此处输入图像描述”>
解决方案:
我找到了解决方案。我没有创建新的位图,而是跳过了头信息的前54个字节,然后存储了字节数组。
MemoryStream memoryStream = new MemoryStream();
bitmap.Save(memoryStream, ImageFormat.Bmp);
// Skip header
IEnumerable<byte> bytes = memoryStream.ToArray().Skip(54);
标准BMP格式允许以经典的上/下顺序或相反的顺序存储图像的字节。
判断是否以此方式存储图像的方法是检查BMP标头中Height
参数的值:
如果为Height < 0
,则图像的高度为abs(Height)
,并且像素以相反(底部/顶部)的顺序存储。
如果为Height > 0
,则您所期望的情况是,像素按“正常”顺序从上到下。
我想说的是,您的情况是从存储有负Height
标头的图像开始(出于某些原因,SVG
对象必须这样做)。但是您无需检查它,因此可以按照从下到上的顺序存储像素。
当与BMP
对象一起存储时,它会从上下文中为您指出这一点。但是,当您仅导出像素时,加载图像的第三方应用程序会看到正Height
,因此将图像上下颠倒显示。
您可以在Wikipedia page for BMP file format中找到有关此像素顺序的详细信息。
编辑:
因此,当您将BMP文件写入磁盘时,必须执行以下操作:
检查您的字节是从上到下(a)还是从下到上(b)
如果(a):将图像的height
作为正值放在BMP标头中
If(b):将- height
作为负值放入BMP标头中。这样,显示您的图像的第三方程序就知道它是反向的。
我找到了解决方案。我没有创建新的位图,而是跳过了头信息的前54个字节,然后存储了字节数组。
MemoryStream memoryStream = new MemoryStream();
bitmap.Save(memoryStream, ImageFormat.Bmp);
// Skip header
IEnumerable<byte> bytes = memoryStream.ToArray().Skip(54);
我遇到了同样的问题,但仍然需要一个基本的64位字符串(用于HTML5画布)。因此,我使用Image类旋转图像,将其存储在新流中,然后转换为base64字符串。
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());