簡體   English   中英

轉換為 Base64 時從字節數組獲得反轉圖像

[英]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 文件寫入磁盤時,您必須執行以下操作:

  1. 檢查您的字節是按從上到下的順序 (a) 還是按從下到上的順序 (b)

  2. 如果(a):將圖像的height作為 BMP 標題中的正值

  3. 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM