像素化可以认为是马赛克,是比较常见的滤镜了,也是一个比较简单的滤镜。在很多的移动图像处理软件中都有这个功能,可以实现交互指定需要马赛克的地方。下图是实现的一些效果:
实现原理:
设定马赛克块的大小,统计每个块中所有像素的平均值,以平均值代替每个块中的像素值即是马赛克的效果。如8x8的块,将64个像素加起来求均值,将均值赋值给这个64个像素(每个块中的像素值都是一样的)。
for (y1 = 0, y2 = 0; y1 < height; )
{
// collect pixels
memset(tmpR,0,sizeof(int)*len);
memset(tmpG,0,sizeof(int)*len);
memset(tmpB,0,sizeof(int)*len);
// calculate
for ( i = 0; ( i < hr ) && ( y1 < height ); i++, y1++ )
{
// for each pixel
for ( x = 0; x < width; x++, src+=3 )
{
tmpR[(int) ( x / wr )] += *src;
tmpG[(int) ( x / wr )] += *(src+1);
tmpB[(int) ( x / wr )] += *(src+2);
}
}
// get average values
t1 = i * wr;
t2 = i * rem;
for ( j = 0; j < len - 1; j++ )
{
tmpR[j] /= t1;
tmpG[j] /= t1;
tmpB[j] /= t1;
}
tmpR[j] /= t2;
tmpG[j] /= t2;
tmpB[j] /= t2;
// save average value to destination image
for ( i = 0; ( i < hr ) && ( y2 < height ); i++, y2++ )
{
// for each pixel
for ( x = 0; x < width; x++, dst+=3 )
{
*dst = (unsigned char) tmpR[(int) ( x / wr )];
*(dst+1) = (unsigned char) tmpG[(int) ( x / wr )];
*(dst+2) = (unsigned char) tmpB[(int) ( x / wr )];
}
}
}
较为复杂的马赛克效果可以是菱形,而不是正方形,这时候就需要通过角度来计算每个块所包含的像素值,原理和上面一样。
美图秀秀中有局部马赛克的功能就是这样实现的:
如何做到上述鼠标经过的地方出现马赛克,有一张原始图和处理之后的马赛克图像,两张图像叠加后可以出现上述的效果,鼠标经过的地方出现处理之后的马赛克的图,未经过的地方出现原始图。