以 **24 位彩色轉灰階** 為例,系統對比 C# 三大影像處理技法:**GetPixel/SetPixel(像素提取)**、**LockBits + Marshal.Copy(記憶體複製)**、**LockBits + unsafe 指標(指標操作)**,並給出完整代碼與性能特徵分析。
Gray = 0.299*R + 0.587*G + 0.114*B(符合人眼亮度感知)Gray = G(綠色權重最高,極速近似)if (bitmap != null) {
var newBmp = bitmap.Clone() as Bitmap;
for (int x = 0; x < newBmp.Width; x++) {
for (int y = 0; y < newBmp.Height; y++) {
Color px = newBmp.GetPixel(x, y);
int gray = (int)(px.R * 0.299 + px.G * 0.587 + px.B * 0.114);
newBmp.SetPixel(x, y, Color.FromArgb(gray, gray, gray));
}
}
pictureBox1.Image = newBmp.Clone() as Image;
}
if (bitmap != null) {
var newBmp = bitmap.Clone() as Bitmap;
var rect = new Rectangle(0, 0, newBmp.Width, newBmp.Height);
var bmpData = newBmp.LockBits(rect, ImageLockMode.ReadWrite, newBmp.PixelFormat);
IntPtr ptr = bmpData.Scan0;
int bytes = newBmp.Width * newBmp.Height * 3; // 24bpp = 3 bytes/px
byte[] rgb = new byte[bytes];
Marshal.Copy(ptr, rgb, 0, bytes); // 非託管→託管陣列
for (int i = 0; i < rgb.Length; i += 3) {
double gray = rgb[i+2]*0.299 + rgb[i+1]*0.587 + rgb[i]*0.114; // BGR 順序
byte g = (byte)gray;
rgb[i] = rgb[i+1] = rgb[i+2] = g;
}
Marshal.Copy(rgb, 0, ptr, bytes); // 託管→非託管
newBmp.UnlockBits(bmpData);
pictureBox1.Image = newBmp.Clone() as Image;
}
PixelFormat.Format24bppRgb 記憶體佈局為 **BGR** 順序(非 RGB),Stride 可能大於 Width*3(記憶體對齊),實際處理時應用 bmpData.Stride 計算行偏移。// 需專案屬性 → Build → Allow unsafe code
unsafe {
var bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
byte* ptr = (byte*)bmpData.Scan0.ToPointer();
int width = bmpData.Width, height = bmpData.Height, stride = bmpData.Stride;
for (int y = 0; y < height; y++) {
byte* row = ptr + y * stride;
for (int x = 0; x < width; x++) {
byte b = row[x*3], g = row[x*3+1], r = row[x*3+2];
byte gray = (byte)(r*0.299 + g*0.587 + b*0.114);
row[x*3] = row[x*3+1] = row[x*3+2] = gray;
}
}
bmp.UnlockBits(bmpData);
}
unsafe、/unsafe 編譯選項、高權限、GC 不掃描指針區域(需手動固定或用 fixed)。| 技法 | 相對速度 | 安全性 | 適用場景 |
|---|---|---|---|
| GetPixel/SetPixel | 1x (基準) | 完全安全 | 教學、原型、極小圖片(<100x100) |
| Marshal.Copy 陣列 | 50-100x | 安全 | **生產環境首選**、中大型圖片、批次處理 |
| unsafe 指標 | 100-500x | 需謹慎 | 高性能即時處理、視訊幀、大量並發 |
**建議**:預設使用 **技法二(記憶體複製法)**,兼顧性能、安全與可維護性;僅在經證實為瓶頸且環境允許時升級至技法三。