C# 將圖片儲存於資料庫 / 從資料庫中讀取圖片 (Image to SQL Server / Image From SQL Server)

2022-04-25

說明如何使用 .NET Framework 使用 C# 將圖片存入 SQL Server Image DataType 欄位之中,以及反向從資料庫 Image DataType 欄位取回圖片,並寫成 PNG File 的方式保存在實體路徑 😃

logo

說明

資料庫的資料表名稱為 ItemImage 資料格式如下

CREATE TABLE [dbo].[ItemImage](
	[ImageNo] [int] NOT NULL Primary Key,
	[ImageContent] [image] NOT NULL,
)

要讀取的資料夾當中的圖片格式如下,數量約五百張。

cd C:\Images

1.png
2.png
5.png
10.png
15.png

Save Image To Dataase

首先使用 EntityFramework 的方式,連線資料庫並使用 Database First 的方式建立資料模型 ItemImage.cs

ItemImage.cs

public partial class ItemImage
{
    public int ImageNo { get; set; }
    public byte[] ImageContent { get; set; }
}

儲存的方式參考 stackoverflow 上 Max Voisard 以及 jethro 回答的 How to save image in database using C#

首先是處理將圖片存入資料庫的程式碼本身,先使用 Directory.GetFiles 迭代資料夾的所有檔案。

接著使用 Image 建立圖片物件,並且使用 FromFile 的方式從實體路徑載入圖片。

為了要將圖片能夠儲存在資料庫的 byte[] 型別欄位,要將資料轉為 Stream。於是先建立 MemoryStram,並且將圖片儲存入 MemoryStream 當中,並指定 Format 為 Png。

使用 stream.Seek 設定資料流的正確位置,如果沒有使用會讓存入資料庫的圖片不正確。

接著建立 byte[] 變數,並且使用 stream.Read 存入 stream 當中。

最後使用 entityFramework 將 image 存入模型,全部都完成之後再一次進行 db.saveChanges()

Program.cs

using System.Drawing;
using System.Drawing.Imaging;
using System.IO;

string[] files = Directory.GetFiles(@"C:\Images");

foreach (var file in files)
{
    string fileName = file.Split('\\').Last().Replace(".png", "");
    int fileNo = Int32.Parse(fileName);

    Image image = Image.FromFile(file);
    MemoryStream stream = new MemoryStream();
    image.Save(stream, ImageFormat.Png);
    stream.Seek(0, SeekOrigin.Begin);
    byte[] imgBytes = new byte[4096];
    stream.Read(imgBytes, 0, 4096);

    db.ItemImage.Add(
        new ItemImage { ImageContent = imgBytes, ImageNo = tansNum }
    );
    image.Dispose();
}

db.SaveChanges();

Load Image From DB

從資料庫取得圖片後,建立 Image 物件,使用 FromStream 搭配 MemoryStream 讀取圖片為 Image 物件。

使用 Save Method,將圖片儲存在實體路徑,完成後對 image 進行資源釋放 Dispose

var dbImage = db.ItemImage.FirstOrDefault(i => i.ImageNo == imageNo);
Image image = Image.FromStream(new MemoryStream(dbImage.ImageContent));
image.Save(@"C:\Images\imgfromdb.png", ImageFormat.Png);
image.Dispose();

Load Image From DB To Base64

public static string GetImageBase64(byte[] imageBytes)
{
    if (imageBytes == null)
    {
        return "";
    }

    MemoryStream ms = new MemoryStream();
    Image image = System.Drawing.Image.FromStream(new MemoryStream(imageBytes));
    image.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
    image.Dispose();
    return Convert.ToBase64String(ms.ToArray());
}
<img src="data:image/png;base64,@GetImageBase64(imageBytes)"/>