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

GDI+ 進階議題:效能優化(四)——LockBits 高速像素存取與指標操作

     編輯:關於.NET

5. 讀圖快了,處理為何仍慢?

Bitmap.GetPixel/SetPixel 極度低效,處理 500 萬像素圖片可能需數分鐘。正解:LockBits 鎖定記憶體區域,直接操作原始位元組。

錯誤示範(GetPixel/SetPixel)

for (int y=0; y

高速寫法

FileStream fs = new FileStream(image, FileMode.Open, FileAccess.Read);
Image img = Image.FromStream(fs, false, false);
Bitmap bmp = new Bitmap(img);
img.Dispose(); fs.Close();

int w = bmp.Width, h = bmp.Height; // 避免重複存取屬性
BitmapData bmData = bmp.LockBits(new Rectangle(0,0,w,h), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
byte* p = (byte*)bmData.Scan0;
int offset = bmData.Stride - w * 3; // Format24bppRgb 每像素 3 bytes

for (int y=0; y

關鍵細節

  • Stride 與 Offset: BMP 標準要求每行位元組數為 4 的倍數。Stride = 行寬 + 填充。Offset = Stride - 實際資料寬度。
  • 邊界檢查: p[2] += 20 可能溢位。安全寫法:
    p[2] = (byte)Math.Min(byte.MaxValue, p[2] + 20); 或 checked((byte)(p[2]+20))。
  • 小端序: 記憶體順序 BGR,紅色在索引 2。

極致優化方向

  1. 自行解碼: 繞過 GDI+ 讀取,直接解析 BMP/JPEG(需自行實作 DCT/霍夫曼解碼)。
  2. SIMD 指令集: 使用 MMX/SSE 並行處理 4-16 位元組。需 C++ 撰寫 DLL 再透過 Interop 呼叫,C# 無法直接使用。

LockBits 速度已接近原生 GDI,一般應用足夠。

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