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

C# 圖像處理:馬賽克效果高性能實現與原理解析

     編輯:關於C#

一、馬賽克算法核心原理

將圖像劃分為 val × val 像素塊,每塊內所有像素統一為該塊左上角像素的顏色。邊緣不足塊大小的區域同理處理。本質是「以線帶面」:掃描行,按塊記錄基準色,填充塊內其餘像素;非基準行直接復制上一行數據。

示意(val=2):

原像素:      馬賽克後:
A B C D      A A C C
E F G H  →   A A C C
I J K L      I I K K
M N O P      I I K K

二、高性能不安全代碼實現

使用 Bitmap.LockBits 獲取內存直訪指針,配合 unsafe 上下文逐像素操作,避免 GetPixel/SetPixel 的極慢托管調用。

public static Bitmap ApplyMosaic(Bitmap source, int blockSize) {
    if (source == null) return null;
    if (blockSize <= 1) return source; // 無效塊大小直接返回

    int w = source.Width, h = source.Height;
    int stdR = 0, stdG = 0, stdB = 0;
    
    // 鎖定位圖內存,格式 24bppRgb (3 bytes/pixel: BGR 順序)
    BitmapData data = source.LockBits(
        new Rectangle(0, 0, w, h), 
        ImageLockMode.ReadWrite, 
        PixelFormat.Format24bppRgb);
    
    unsafe {
        byte* ptr = (byte*)data.Scan0;
        int stride = data.Stride; // 行跨度(含內存對齊填充)
        
        for (int y = 0; y < h; y++) {
            byte* rowPtr = ptr + y * stride;
            for (int x = 0; x < w; x++) {
                byte* pixel = rowPtr + x * 3;
                
                if (y % blockSize == 0) { // 基準行
                    if (x % blockSize == 0) { // 基準列:記錄基準色
                        stdR = pixel[2]; stdG = pixel[1]; stdB = pixel[0];
                    } else { // 同塊內其餘列:填充基準色
                        pixel[0] = (byte)stdB; pixel[1] = (byte)stdG; pixel[2] = (byte)stdR;
                    }
                } else { // 非基準行:直接復制上一行同列像素
                    byte* upperPixel = pixel - stride;
                    pixel[0] = upperPixel[0]; pixel[1] = upperPixel[1]; pixel[2] = upperPixel[2];
                }
            }
        }
    }
    source.UnlockBits(data);
    return source;
}

三、關鍵性能優化點解析

  1. LockBits + 指針:繞過托管邊界檢查,直接操作非托管內存,速度提升 100 倍以上。
  2. 行指針緩存:外層循環計算 rowPtr,內層避免重複乘法。
  3. Stride 處理:正確處理內存對齊填充字節,避免圖像傾斜/損壞。
  4. BGR 順序:Format24bppRgb 內存實際為 BGR,讀寫時注意 [0]=B, [1]=G, [2]=R。
  5. 邊界條件:blockSize <= 1 直接返回,避免無限循環/除零。

四、安全代碼替代方案(無 unsafe)

public static Bitmap ApplyMosaicSafe(Bitmap source, int blockSize) {
    if (source == null || blockSize <= 1) return source;
    int w = source.Width, h = source.Height;
    Bitmap result = new Bitmap(w, h, PixelFormat.Format24bppRgb);
    
    using (Graphics g = Graphics.FromImage(result)) {
        g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
        // 縮小再放大產生馬賽克效果(GPU 加速,極快)
        int sw = Math.Max(1, w / blockSize);
        int sh = Math.Max(1, h / blockSize);
        using (Bitmap small = new Bitmap(source, sw, sh)) {
            g.DrawImage(small, 0, 0, w, h);
        }
    }
    return result;
}

此法利用 NearestNeighbor 插值模式 + 縮放繪圖,代碼簡潔、無需 unsafe、自動利用 GPU 加速,適合大多數業務場景。

五、應用場景與擴展

  • 隱私保護:人臉、車牌、敏感文檔模糊化。
  • 藝術特效:像素風格化、復古遊戲畫面。
  • 數據增強:訓練數據遮擋擴展。
  • 擴展思路:隨機塊大小、圓形馬賽克、漸變邊緣、動態塊大小(基於圖像熵)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved