首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 圖片縮圖與壓縮:員工照片資料庫儲存最佳實務

     編輯:關於C語言

需求場景

員工管理系統需儲存大頭照。原始照片 1024×768、2MB,直接存入資料庫造成:

  • 資料庫膨脹、備份/還原緩慢。
  • 網路傳輸頻寬浪費 (特別是 Web/行動端)。
  • UI 載入延遲、記憶體壓力。

解決方案:**上傳時即時產生縮圖 + JPEG 壓縮**,僅儲存 5~10KB 縮圖。

核心程式碼 (System.Drawing.Common)


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

public static class ImageHelper
{
    /// 
    /// 產生縮圖並壓縮為 JPEG 位元組陣列
    /// 
    /// 來源圖片路徑
    /// 最大寬度
    /// 最大高度
    /// JPEG 品質 1~100 (建議 75~85)
    /// JPEG 位元組陣列,可直接寫入資料庫 VARBINARY/IMAGE/BLOB 欄位
    public static byte[] CreateThumbnailToBytes(string sourcePath, int maxWidth = 120, int maxHeight = 160, long quality = 80L)
    {
        using (var original = Image.FromFile(sourcePath))
        using (var thumbnail = CreateThumbnail(original, maxWidth, maxHeight))
        using (var ms = new MemoryStream())
        {
            var encoder = GetEncoder(ImageFormat.Jpeg);
            var params = new EncoderParameters(1);
            params.Param[0] = new EncoderParameter(Encoder.Quality, quality);
            thumbnail.Save(ms, encoder, params);
            return ms.ToArray();
        }
    }

    /// 
    /// 等比例縮放,維持長寬比
    /// 
    public static Image CreateThumbnail(Image source, int maxWidth, int maxHeight)
    {
        double ratioX = (double)maxWidth / source.Width;
        double ratioY = (double)maxHeight / source.Height;
        double ratio = Math.Min(ratioX, ratioY);

        int newWidth = (int)(source.Width * ratio);
        int newHeight = (int)(source.Height * ratio);

        var dest = new Bitmap(newWidth, newHeight);
        using (var g = Graphics.FromImage(dest))
        {
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.CompositingQuality = CompositingQuality.HighQuality;
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.DrawImage(source, 0, 0, newWidth, newHeight);
        }
        return dest;
    }

    private static ImageCodecInfo GetEncoder(ImageFormat format)
    {
        return ImageCodecInfo.GetImageDecoders().FirstOrDefault(c => c.FormatID == format.Guid);
    }
}

資料庫存取範例 (ADO.NET)


// 存入
byte[] photoBytes = ImageHelper.CreateThumbnailToBytes(@"C:\Photos\emp001.jpg", 120, 160, 80);
using (var conn = new SqlConnection(connStr))
using (var cmd = new SqlCommand("UPDATE Employee SET Photo = @photo WHERE Id = @id", conn))
{
    cmd.Parameters.Add("@photo", SqlDbType.VarBinary, -1).Value = photoBytes;
    cmd.Parameters.AddWithValue("@id", empId);
    conn.Open();
    cmd.ExecuteNonQuery();
}

// 讀出並繫結 PictureBox (WinForms)
using (var conn = new SqlConnection(connStr))
using (var cmd = new SqlCommand("SELECT Photo FROM Employee WHERE Id = @id", conn))
{
    cmd.Parameters.AddWithValue("@id", empId);
    conn.Open();
    byte[] bytes = (byte[])cmd.ExecuteScalar();
    if (bytes != null && bytes.Length > 0)
    {
        using (var ms = new MemoryStream(bytes))
        {
            pictureBox1.Image = Image.FromStream(ms);
        }
    }
}

Web 環境優化 (ASP.NET Core)


// Controller 上傳端點
[HttpPost]
public async Task UploadPhoto(IFormFile file, int empId)
{
    if (file == null || file.Length == 0) return BadRequest();

    using (var ms = new MemoryStream())
    {
        await file.CopyToAsync(ms);
        ms.Position = 0;
        using (var img = Image.Load(ms)) // 建議用 ImageSharp 取代 System.Drawing (跨平台)
        {
            img.Mutate(x => x.Resize(new ResizeOptions
            {
                Mode = ResizeMode.Max,
                Size = new Size(120, 160)
            }));
            using (var outMs = new MemoryStream())
            {
                img.SaveAsJpeg(outMs, new JpegEncoder { Quality = 80 });
                byte[] bytes = outMs.ToArray();
                // 存入資料庫...
            }
        }
    }
    return Ok();
}

// 讀取端點 (回傳檔案流)
[HttpGet("{empId}")]
public async Task GetPhoto(int empId)
{
    byte[] bytes = await _repo.GetPhotoAsync(empId);
    if (bytes == null) return NotFound();
    return File(bytes, "image/jpeg"); // 瀏覽器直接顯示、快取
}

關鍵建議

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
面向建議
函式庫選擇**ImageSharp (SixLabors.ImageSharp)**:純 managed、跨平台 (Linux/Docker/ARM)、無 GDI+ 相依、記憶體安全、支援 .NET Core/.NET 5+。
**System.Drawing.Common** 僅支援 Windows、Linux 需安裝 libgdiplus、易發生 GDI+ 通用錯誤。
儲存策略資料庫僅存縮圖 (≤50KB);原圖存物件儲存 (Azure Blob/S3/MinIO/NAS),資料庫存 URL/路徑。
格式選擇JPEG (照片)、WebP (現代瀏覽器、體積更小)、PNG (需透明背景)。
安全性驗證 MIME 型別、檔案簽名 (Magic Number)、限制上傳大小、掃描惡意軟體。
效能非同步 I/O、串流處理避免大記憶體佔用、CDN 快取縮圖。