图像马赛克效果其实就是将图像分成大小一致的图像块,每一个图像块都是一个正方形,并且在这个正方形中所有像素值都相等。我们可以将这个正方形看作是一个模板窗口,模板中对应的所有图像像素值都等于该模板的左上角第一个像素的像素值,这样的效果就是马赛克效果,而正方形模板的大小则决定了马赛克块的大小,即图像马赛克化的程度。
核心代码如下:
///
/// Mosaic filter.
///
/// Source image.
/// The size of mosaic effect.
/// Resullt image.
public Bitmap MosaicFilter(Bitmap src, int blockSize)
{
Bitmap srcBitmap = new Bitmap(src);
int w = srcBitmap.Width;
int h = srcBitmap.Height;
System.Drawing.Imaging.BitmapData srcData = srcBitmap.LockBits(new Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
IntPtr ptr = srcData.Scan0;
int bytes = h * srcData.Stride;
byte[] srcValues = new byte[bytes];
System.Runtime.InteropServices.Marshal.Copy(ptr, srcValues, 0, bytes);
byte[] tempValues = (byte[])srcValues.Clone();
int stride = srcData.Stride;
int b = 0, g = 0, r = 0;
int dR = 0;
int dG = 0;
int dB = 0;
int dstX = 0;
int dstY = 0;
blockSize = Math.Min(blockSize, (w + h) / 2);
for (int j = 0; j < h; j++)
{
for (int i = 0; i < w; i++)
{
b = srcValues[i * 4 + j * w * 4];
g = srcValues[i * 4 + 1 + j * w * 4];
r = srcValues[i * 4 + 2 + j * w * 4];
dstX = i;
dstY = j;
if (j % blockSize == 0)
{
if (i % blockSize == 0)
{
dB = srcValues[dstX * 4 + dstY * w * 4];
dG = srcValues[dstX * 4 + 1 + dstY * w * 4];
dR = srcValues[dstX * 4 + 2 + dstY * w * 4];
}
else
{
tempValues[dstX * 4 + dstY * w * 4] = (byte)dB;
tempValues[dstX * 4 + 1 + dstY * w * 4] = (byte)dG;
tempValues[dstX * 4 + 2 + dstY * w * 4] = (byte)dR;
}
}
else
{
tempValues[dstX * 4 + dstY * w * 4] = tempValues[dstX * 4 + (dstY - 1) * w * 4];
tempValues[dstX * 4 + 1 + dstY * w * 4] = tempValues[dstX * 4 + 1 + (dstY - 1) * w * 4];
tempValues[dstX * 4 + 2 + dstY * w * 4] = tempValues[dstX * 4 + 2 + (dstY - 1) * w * 4];
}
}
}
srcValues = (byte[])tempValues.Clone();
System.Runtime.InteropServices.Marshal.Copy(srcValues, 0, ptr, bytes);
srcBitmap.UnlockBits(srcData);
return srcBitmap;
}
程序demo:点击打开链接