[英]Got Reversed Image from Byte Array when converting to Base64
我只需要獲取原始位圖數據(無標題或其他信息)。 我使用以下代碼來獲取位圖數據:
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 轉換無關。 似乎字節順序相反。
當我使用代碼保存圖像時,圖像如下所示:
當我使用字節時,我會看到:
解決方案:
我找到了解決方案。 我沒有創建新的位圖,而是跳過了頭信息的前 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
並因此顛倒顯示您的圖像。
您可以在BMP 文件格式的Wikipedia 頁面中找到有關此像素排序的詳細信息。
編輯:
因此,當您將 BMP 文件寫入磁盤時,您必須執行以下操作:
檢查您的字節是按從上到下的順序 (a) 還是按從下到上的順序 (b)
如果(a):將圖像的height
作為 BMP 標題中的正值
If (b): put - height
作為 BMP 標頭中的負值。 以便顯示您的圖像的第三方程序知道它已反轉。
我找到了解決方案。 我沒有創建新的位圖,而是跳過了頭信息的前 54 個字節,然后存儲了字節數組。
MemoryStream memoryStream = new MemoryStream();
bitmap.Save(memoryStream, ImageFormat.Bmp);
// Skip header
IEnumerable<byte> bytes = memoryStream.ToArray().Skip(54);
我遇到了同樣的問題,但仍然需要一個 base 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());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.