public Image BytesToImage(byte[] imageData)
{
if (imageData == null || imageData.Length == 0) return null;
using (var ms = new MemoryStream(imageData))
{
// 驗證圖片格式,避免惡意資料導致 GDI+ 例外
try { return Image.FromStream(ms, useEmbeddedColorManagement: true, validateImageData: true); }
catch (ArgumentException) { throw new InvalidDataException("資料非有效圖片格式"); }
}
}
Image.FromStream 僅支援 BMP、PNG、JPEG、GIF、TIFF、ICO、WMF、EMF。ArgumentException。若同一 MemoryStream 讀取多次(如先驗證再顯示),需在每次 Image.FromStream 前執行 ms.Position = 0;。
Image.FromFile 暫存檔或 BitmapDecoder 串流解碼。BitmapImage + StreamSource 享受 UI 虛擬化。using (var conn = new SqlConnection(cs))
using (var cmd = new SqlCommand("SELECT Photo FROM Employees WHERE Id=@id", conn))
{
cmd.Parameters.AddWithValue("@id", id);
conn.Open();
// ExecuteScalar 適用單一欄位
var bytes = (byte[])cmd.ExecuteScalar();
return BytesToImage(bytes);
}
| 錯誤訊息 | 原因 | 解決 |
|---|---|---|
| Parameter is not valid | Byte 陣列損毀/非圖片 | 寫入前驗證 Magic Number (FF D8 FF / 89 50 4E 47) |
| Out of memory | 大圖載入 LOH 碎片 | 分塊解碼 / 降低解析度 / 改用 SkiaSharp |
| Access denied | GDI+ 需臨時檔案權限 | 確保 IIS_IUSRS 對 %TEMP% 有寫入權 |
string base64 = Convert.ToBase64String(imageData);
string dataUrl = $"data:image/png;base64,{base64}"; // 直接用於 <img src=...>
MemoryStream + Image.FromStream 是標準做法,關鍵在於輸入驗證、串流管理與例外處理。建議在資料寫入資料庫時同步檢查檔案簽名,源頭把關,避免髒資料污染。