每像素各通道值 = 255 - 原值。對 24-bit BMP (BGR 順序),逐行處理:
void __fastcall InvertBitmap(Graphics::TBitmap* Bmp)
{
if (!Bmp || Bmp->PixelFormat != pf24bit) return; // 僅處理 24-bit
for (int y = 0; y < Bmp->Height; ++y) {
BYTE* row = (BYTE*)Bmp->ScanLine[y];
for (int x = 0; x < Bmp->Width * 3; ++x) {
row[x] = 255 - row[x];
}
}
}
ScanLine[y] 返回第 y 行像素緩衝區指標,**直接記憶體操作**,比 Canvas->Pixels[x][y] 快 100~1000 倍。ScanLine 已處理行對齊)。void __fastcall InvertBitmap32(Graphics::TBitmap* Bmp)
{
if (!Bmp || Bmp->PixelFormat != pf32bit) return;
for (int y = 0; y < Bmp->Height; ++y) {
BYTE* row = (BYTE*)Bmp->ScanLine[y];
for (int x = 0; x < Bmp->Width; ++x) {
row[x*4 + 0] = 255 - row[x*4 + 0]; // B
row[x*4 + 1] = 255 - row[x*4 + 1]; // G
row[x*4 + 2] = 255 - row[x*4 + 2]; // R
// row[x*4 + 3] 保持 Alpha 不變
}
}
}
template
void ForEachPixel(Graphics::TBitmap* Bmp, PixelOp op) {
int bytesPerPixel = 0;
switch (Bmp->PixelFormat) {
case pf24bit: bytesPerPixel = 3; break;
case pf32bit: bytesPerPixel = 4; break;
case pf16bit: bytesPerPixel = 2; break; // 5:6:5 需特殊解碼
default: return;
}
for (int y = 0; y < Bmp->Height; ++y) {
BYTE* row = (BYTE*)Bmp->ScanLine[y];
for (int x = 0; x < Bmp->Width; ++x) {
op(row + x * bytesPerPixel, bytesPerPixel);
}
}
}
// 使用
ForEachPixel(bmp, [](BYTE* px, int bpp) {
if (bpp >= 3) {
px[0] = 255 - px[0];
px[1] = 255 - px[1];
px[2] = 255 - px[2];
}
});
| 圖片尺寸 | 像素數 | ScanLine 反色耗時 | Canvas.Pixels 耗時 |
|---|---|---|---|
| 1920x1080 | 2.07M | ~3 ms | ~1200 ms |
| 4000x3000 | 12M | ~18 ms | ~7000 ms |