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

C# 繪製 8 位彩色圖片(自訂調色盤)

     編輯:關於C#

前言

.NET System.Drawing 支援 8bpp 索引色彩模式,配合自訂調色盤可大幅減少檔案大小,適合顏色數有限的圖表、股票走勢圖等。

核心步驟

  1. 載入原始圖片。
  2. 取得對應色數的調色盤(GetColorPalette)。
  3. 定義自訂顏色清單並寫入調色盤前 N 筆。
  4. 建立 8bpp 位圖,鎖定位元資料逐像素映射顏色索引。
  5. 儲存為 GIF 格式保留索引色彩。

關鍵程式碼片段

取得調色盤

public static ColorPalette GetColorPalette(uint colorCount) {
    PixelFormat fmt = PixelFormat.Format1bppIndexed;
    if (colorCount > 2) fmt = PixelFormat.Format4bppIndexed;
    if (colorCount > 16) fmt = PixelFormat.Format8bppIndexed;
    using (Bitmap bmp = new Bitmap(1, 1, fmt))
        return bmp.Palette;
}

自訂調色盤並繪製

public static void SaveGIFWithNewColorTable(Image src, ColorPalette pal, string filename) {
    int w = src.Width, h = src.Height;
    Bitmap dst = new Bitmap(w, h, PixelFormat.Format8bppIndexed);
    dst.Palette = pal;

    // 將來源繪製到 32bpp 暫存位圖以便取像素
    Bitmap tmp = new Bitmap(w, h, PixelFormat.Format32bppArgb);
    using (Graphics g = Graphics.FromImage(tmp)) {
        g.DrawImage(src, 0, 0, w, h);
    }

    // 鎖定位元資料
    Rectangle rect = new Rectangle(0, 0, w, h);
    BitmapData dstData = dst.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
    BitmapData tmpData = tmp.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

    unsafe {
        byte* dstPtr = (byte*)dstData.Scan0;
        byte* srcPtr = (byte*)tmpData.Scan0;
        int dstStride = dstData.Stride;
        int srcStride = tmpData.Stride;

        for (int y = 0; y < h; y++) {
            byte* dstRow = dstPtr + y * dstStride;
            byte* srcRow = srcPtr + y * srcStride;
            for (int x = 0; x < w; x++) {
                // 取得 32bpp 像素顏色 (BGRA)
                Color pixel = Color.FromArgb(srcRow[3], srcRow[2], srcRow[1], srcRow[0]);
                srcRow += 4;
                // 找顏色在調色盤索引
                dstRow[x] = (byte)colorList.IndexOf(pixel);
            }
        }
    }
    dst.UnlockBits(dstData);
    tmp.UnlockBits(tmpData);
    dst.Save(filename, ImageFormat.Gif);
    dst.Dispose(); tmp.Dispose();
}

效能優化提示

逐像素 IndexOf 搜尋較慢,可改用 switch 或依顏色特徵值(如 G 通道)直接判斷索引,大幅提升速度。

完整範例下載

原文提供完整專案原始碼,含灰階版本 SaveGIFWithNewGrayscale 供參考。

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