1. 程式人生 > >Android影象處理-畫素化的原理及實現

Android影象處理-畫素化的原理及實現

部落格地址: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()
);

效果如下: