Android影象處理-畫素化的原理及實現
阿新 • • 發佈:2019-02-06
部落格地址:xiazdong.github.io
馬賽克演算法首先需要確定馬賽克單元的大小,即小方塊的大小。馬賽克圖的每個馬賽克單元都是純色的塊,其取值一般為原圖中該塊區域的顏色的均值(這裡的實現為了簡化,取了原圖中該區域左上角的畫素)。馬賽克單元的大小決定了最後的馬賽克圖的樣子,當值為1時,就是原圖。
上圖中,最左邊的圖是原圖,中間的圖是馬賽克圖。當然你也可以對影象的某塊區域打馬賽克,如最右邊的圖,他只對頭部打馬賽克。
演算法實現如下:
public class PixelateUtil {
/
普通影象->畫素圖,zoneWidth為畫素圖的大畫素的寬度
/
publicstatic Bitmap pixelate(Bitmap bitmap, int zoneWidth) {
return pixelate(bitmap, zoneWidth, 0, 0, bitmap.getWidth(), bitmap.getHeight());
}
/
普通圖->畫素圖,left、top、right、bottom可指定打馬賽克區域
/
publicstatic Bitmap pixelate(Bitmap bitmap, int zoneWidth, int left, int top, int right, int bottom) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
Bitmap result = bitmap.copy(Bitmap.Config.ARGB_8888, true);
Canvas canvas = new Canvas(result);
Paint paint = new Paint();
for (int i = left; i < right; i += zoneWidth) {
for (int j = top; j < bottom; j += zoneWidth) {
int color = bitmap.getPixel(i, j);
paint.setColor(color);
int gridRight = Math.min(w, i + zoneWidth);
int gridBottom = Math.min(h, j + zoneWidth);
canvas.drawRect(i, j, gridRight, gridBottom, paint);
}
}
return result;
}
}
使用方法:
Bitmap result = PixelateUtil.pixelate(bitmap, zoneWidth); //對全圖打馬賽克
Bitmap result = PixelateUtil.pixelate(bitmap, zoneWidth, left, top, right, bottom); //對指定區域打馬賽克
開源專案
Pixelate是實現基本馬賽克效果的開源專案,它能夠非同步對整個或者部分的Bitmap區域打馬賽克,處理完後會在OnPixelateListener的onPixelated()中回撥,最小的SDK版本為16。
使用方法如下:
new Pixelate(origin)
.setArea(0,0,origin.getWidth(),origin.getHeight()) //設定區域
.setDensity(12) //值越大,馬賽克單元越小
.setListener(new OnPixelateListener() {
@Override
publicvoidonPixelated(Bitmap bitmap, int density){
//bitmap為馬賽克圖
Log.v(TAG, "");
}
})
.make();
Bitmap pixelated = Pixelate.fromBitmap(
origin,
new PixelateLayer.Builder(PixelateLayer.Shape.Circle) //設定馬賽克形狀
.setResolution(30) //每個畫素的密度(如果該值和size值一樣,那麼圓形之間相鄰)
.setSize(30) //圓圈的大小
.build()
);
效果如下: