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

C# 高品質縮略圖生成:Graphics 高質量插值與 JPEG 壓縮

     編輯:關於C語言

前言

Bitmap.GetThumbnailImage 生成的縮略圖品質較差。本文展示三種方案遞進:內建方法、Graphics 高質量雙三次插值、加入 JPEG 編碼器參數壓縮,兼顧清晰度與檔案大小。

完整程式碼


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

namespace ThumbnailDemo
{
    class Program
    {
        const int TARGET_W = 190, TARGET_H = 190;

        static void Main()
        {
            string src = @"G:\photos\source.jpg";
            string destDir = @"E:\Thumbnails";

            Method1_GetThumbnailImage(src, destDir);
            Method2_GraphicsHighQuality(src, destDir);
            Method3_GraphicsPlusJpegCompression(src, destDir);

            Console.ReadKey();
        }

        // 方案 1:內建 GetThumbnailImage(品質最低)
        static void Method1_GetThumbnailImage(string src, string destDir)
        {
            using (var source = new Bitmap(src))
            {
                CalcSize(source, out int w, out int h);
                using (var thumb = source.GetThumbnailImage(w, h, null, IntPtr.Zero))
                    thumb.Save(Path.Combine(destDir, "th_1.jpg"));
            }
        }

        // 方案 2:Graphics 高質量雙三次插值
        static void Method2_GraphicsHighQuality(string src, string destDir)
        {
            using (var source = new Bitmap(src))
            {
                CalcSize(source, out int w, out int h);
                using (var thumb = new Bitmap(w, h))
                using (var g = Graphics.FromImage(thumb))
                {
                    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    g.FillRectangle(Brushes.White, 0, 0, w, h);
                    g.DrawImage(source, 0, 0, w, h);
                    thumb.Save(Path.Combine(destDir, "th_2.jpg"));
                }
            }
        }

        // 方案 3:方案 2 + JPEG 壓縮品質 75%
        static void Method3_GraphicsPlusJpegCompression(string src, string destDir)
        {
            // 設定 JPEG 編碼器參數
            var encoderParams = new EncoderParameters(1);
            encoderParams.Param[0] = new EncoderParameter(Encoder.Quality, 75L);
            var jpegCodec = ImageCodecInfo.GetImageEncoders()
                .FirstOrDefault(c => c.FormatDescription == "JPEG");

            using (var source = new Bitmap(src))
            {
                CalcSize(source, out int w, out int h);
                using (var thumb = new Bitmap(w, h))
                using (var g = Graphics.FromImage(thumb))
                {
                    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    g.FillRectangle(Brushes.White, 0, 0, w, h);
                    g.DrawImage(source, 0, 0, w, h);
                    thumb.Save(Path.Combine(destDir, "th_3.jpg"), jpegCodec, encoderParams);
                }
            }
        }

        static void CalcSize(Bitmap source, out int w, out int h)
        {
            w = TARGET_W; h = TARGET_H;
            if (source.Width > source.Height)
                h = (int)(source.Height * ((decimal)TARGET_W / source.Width));
            else
                w = (int)(source.Width * ((decimal)TARGET_H / source.Height));
        }
    }
}

三方案比較

方案清晰度檔案大小速度
1. GetThumbnailImage低(預設雙線性)中最快
2. Graphics HighQualityBicubic高(銳利、無鋸齒)大(無壓縮或預設壓縮)中
3. + JPEG Quality 75%高**小(約方案 2 的 1/10)**中

關鍵技術點

  • InterpolationMode.HighQualityBicubic:雙三次插值,縮放品質最佳。
  • FillRectangle(White):避免透明背景導致黑邊,確保白底。
  • Encoder.Quality:0~100,75% 為品質/大小平衡點。
  • ImageCodecInfo:需透過 GetImageEncoders() 尋找 JPEG 編碼器。
  • 保持長寬比:CalcSize 依長邊縮放,短邊等比例計算。

進階建議

  • 大量處理時,考慮 Parallel.ForEach 並行化。
  • 支援 PNG、WebP 輸出,針對透明圖片調整編碼器。
  • 記憶體管理:大圖片建議分塊處理或使用 Image.FromStream 避免檔案鎖定。

結語

結合 Graphics 高質量插值與 JPEG 編碼器參數,即可獲得兼具清晰度與小體積的縮略圖。方案 3 為實務專案推薦做法。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved