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

C# 實作浮雕效果圖片處理演算法

     編輯:關於C#

演算法原理

浮雕效果透過計算相鄰像素差值產生立體感:

  1. 取得像素 (x, y) 與右下相鄰像素 (x+1, y+1) 的 RGB 值。
  2. 計算差值並加上 128(中性灰):
    R' = |R1 - R2 + 128|
    G' = |G1 - G2 + 128|
    B' = |B1 - B2 + 128|
  3. 將結果限制在 0~255 範圍內。
  4. 將新像素寫入結果圖片。

完整實作程式碼

private void button1_Click(object sender, EventArgs e)
{
    try
    {
        int Height = this.pictureBox1.Image.Height;
        int Width = this.pictureBox1.Image.Width;
        Bitmap newBitmap = new Bitmap(Width, Height);
        Bitmap oldBitmap = (Bitmap)this.pictureBox1.Image;
        Color pixel1, pixel2;

        for (int x = 0; x < Width - 1; x++)
        {
            for (int y = 0; y < Height - 1; y++)
            {
                int r = 0, g = 0, b = 0;
                pixel1 = oldBitmap.GetPixel(x, y);
                pixel2 = oldBitmap.GetPixel(x + 1, y + 1);
                
                r = Math.Abs(pixel1.R - pixel2.R + 128);
                g = Math.Abs(pixel1.G - pixel2.G + 128);
                b = Math.Abs(pixel1.B - pixel2.B + 128);
                
                // 限制範圍 0-255
                r = Math.Max(0, Math.Min(255, r));
                g = Math.Max(0, Math.Min(255, g));
                b = Math.Max(0, Math.Min(255, b));
                
                newBitmap.SetPixel(x, y, Color.FromArgb(r, g, b));
            }
        }
        this.pictureBox1.Image = newBitmap;
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "資訊提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
}

效能優化建議

  • 使用 LockBits:GetPixel/SetPixel 效能極差,大圖處理應使用 Bitmap.LockBits 直接操作記憶體。
  • 平行處理:外層迴圈可用 Parallel.For 多執行緒加速。
  • 避免重複建立 Bitmap:重複套用濾鏡時重複使用緩衝區。

LockBits 高效能版本範例

public static Bitmap EmbossFilter(Bitmap source)
{
    Bitmap result = new Bitmap(source.Width, source.Height, source.PixelFormat);
    Rectangle rect = new Rectangle(0, 0, source.Width, source.Height);
    
    var srcData = source.LockBits(rect, ImageLockMode.ReadOnly, source.PixelFormat);
    var dstData = result.LockBits(rect, ImageLockMode.WriteOnly, result.PixelFormat);
    
    int bytes = Math.Abs(srcData.Stride) * source.Height;
    byte[] srcBytes = new byte[bytes];
    byte[] dstBytes = new byte[bytes];
    
    System.Runtime.InteropServices.Marshal.Copy(srcData.Scan0, srcBytes, 0, bytes);
    
    int stride = srcData.Stride;
    int width = source.Width;
    int height = source.Height;
    
    for (int y = 0; y < height - 1; y++)
    {
        for (int x = 0; x < width - 1; x++)
        {
            int idx1 = y * stride + x * 4;
            int idx2 = (y + 1) * stride + (x + 1) * 4;
            
            int r = Math.Abs(srcBytes[idx1 + 2] - srcBytes[idx2 + 2] + 128);
            int g = Math.Abs(srcBytes[idx1 + 1] - srcBytes[idx2 + 1] + 128);
            int b = Math.Abs(srcBytes[idx1] - srcBytes[idx2] + 128);
            
            dstBytes[idx1 + 2] = (byte)Math.Clamp(r, 0, 255);
            dstBytes[idx1 + 1] = (byte)Math.Clamp(g, 0, 255);
            dstBytes[idx1] = (byte)Math.Clamp(b, 0, 255);
            dstBytes[idx1 + 3] = 255; // Alpha
        }
    }
    
    System.Runtime.InteropServices.Marshal.Copy(dstBytes, 0, dstData.Scan0, bytes);
    source.UnlockBits(srcData);
    result.UnlockBits(dstData);
    return result;
}

相關濾鏡延伸

同樣原理可實作:
• 雕刻效果:使用左上像素與右下像素差值
• 邊緣偵測:Sobel、Prewitt 算子
• 銳化:拉普拉斯算子

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