以下是馬賽克效果的核心實現代碼。雖然演算法設計非我的強項,但這個「能跑就行」的版本已足夠展示核心邏輯,希望能提供參考而非誤導。
public static Bitmap KiMosaic(Bitmap b, int val)
{
if (b == null) return null;
int w = b.Width;
int h = b.Height;
int stdR = 0, stdG = 0, stdB = 0;
BitmapData srcData = b.LockBits(
new Rectangle(0, 0, w, h),
ImageLockMode.ReadWrite,
PixelFormat.Format24bppRgb);
unsafe
{
byte* p = (byte*)srcData.Scan0.ToPointer();
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
if (y % val == 0)
{
if (x % val == 0)
{
// 記錄左上角像素顏色作為該區塊基準色
stdR = p[2]; stdG = p[1]; stdB = p[0];
}
else
{
// 同一行內,沿用最近的基準色
p[0] = (byte)stdB;
p[1] = (byte)stdG;
p[2] = (byte)stdR;
}
}
else
{
// 非基準行:直接複製上一行對應位置的顏色
byte* pTemp = p - srcData.Stride;
p[0] = pTemp[0];
p[1] = pTemp[1];
p[2] = pTemp[2];
}
p += 3; // 移動到下一個像素(24bpp = 3 bytes)
}
// 跳過行尾填充字節,移至下一行開頭
p += srcData.Stride - w * 3;
}
b.UnlockBits(srcData);
}
return b;
}
關鍵點解析:
LockBits + unsafe 指針操作,避免 GetPixel/SetPixel 的極低效率val 參數控制馬賽克方塊大小(val × val 像素)Stride 可能大於 width * 3,需正確處理行尾填充此實現屬於基礎版本,生產環境建議考慮:區塊平均色取樣、邊緣抗鋸齒、多線程並行處理等優化。