圖片處理之涂抹馬賽克

一直想對之前做過的一款圖片社交軟件cos醬(類似in nice)的代碼進行梳理,但是由于時間的關系拖到今天才開始這個工作。
在項目中,主要對照片裁剪、旋轉、翻轉(在之前的文章有提到過)、貼紙、濾鏡、文字、邊框、標簽等功能。

涂抹馬賽克

涂抹主要利用的是paint的setXfermode來進行圖片的疊加

第一步 生成馬賽克圖片

private Bitmap getGridMosaic() { if (mImgBitmap == null) { return null; } int mImageWidth = mImgBitmap.getWidth(); int mImageHeight = mImgBitmap.getHeight(); Bitmap bitmap = Bitmap.createBitmap(mImageWidth, mImageHeight, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); int horCount = (int) Math.ceil(mImageWidth / (float) mGridWidth); int verCount = (int) Math.ceil(mImageHeight / (float) mGridWidth); Paint paint = new Paint(); paint.setAntiAlias(true); for (int horIndex = 0; horIndex < horCount; ++horIndex) { for (int verIndex = 0; verIndex < verCount; ++verIndex) { int l = mGridWidth * horIndex; int t = mGridWidth * verIndex; int r = l + mGridWidth; if (r > mImageWidth) { r = mImageWidth; } int b = t + mGridWidth; if (b > mImageHeight) { b = mImageHeight; } int color = mImgBitmap.getPixel(l, t); Rect rect = new Rect(l, t, r, b); paint.setColor(color); canvas.drawRect(rect, paint); } } canvas.save(); return bitmap; }

第二步 處理觸摸事件

/** * 觸摸事件 * @param event * @return */ public boolean dispatchTouchEvent(MotionEvent event) { super.dispatchTouchEvent(event); if(isTouchable){ int action = event.getAction(); int x = (int) event.getX(); int y = (int) event.getY(); onPathEvent(action, x, y); } return true;} /** * 觸摸事件處理 * @param action * @param x * @param y */ private void onPathEvent(int action, int x, int y) { if (mImgBitmap == null) { return; } int mImageWidth = mImgBitmap.getWidth(); int mImageHeight = mImgBitmap.getHeight(); if (x < mImgDesRect.left || x > mImgDesRect.right || y < mImgDesRect.top || y > mImgDesRect.bottom) { return; } float ratio = (mImgDesRect.right - mImgDesRect.left)/ (float) mImageWidth; x = (int) ((x - mImgDesRect.left) / ratio); y = (int) ((y - mImgDesRect.top) / ratio); if (action == MotionEvent.ACTION_DOWN) { mErasePath = new Path(); mErasePath.moveTo(x, y); dp = new DrawPath(); dp.path = mErasePath; dp.paint = initErasePaint(); dp.isErase = isEraseMode; Log.e("tag", "mMosaic=====" + dp.paint.getStrokeWidth()); } else if (action == MotionEvent.ACTION_MOVE) { dp.path.lineTo(x, y); savePath.add(dp); updatePathMosaic(false,savePath); invalidate(); }else if(action == MotionEvent.ACTION_UP){ historyPath.add(dp); }}

第三步 繪制合成

/** * 是否繪制所有的路徑, 當要撤銷的時候就需要繪制所有的路徑 * @param isDrawAll */ private void updatePathMosaic(boolean isDrawAll,ArrayList<DrawPath> listDrawPath) { if (mImgBitmap == null) { return ; } int mImageWidth = mImgBitmap.getWidth(); int mImageHeight = mImgBitmap.getHeight(); if (bmMosaicLayer != null) { bmMosaicLayer.recycle(); } bmMosaicLayer = Bitmap.createBitmap(mImageWidth, mImageHeight, Bitmap.Config.ARGB_8888); if(bmTouchLayer==null){ bmTouchLayer = Bitmap.createBitmap(mImageWidth, mImageHeight, Bitmap.Config.ARGB_8888); }// 先在bmTouchLayer上繪制出路徑 Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setStyle(Paint.Style.STROKE); paint.setAntiAlias(true); paint.setStrokeJoin(Paint.Join.ROUND); paint.setStrokeCap(Paint.Cap.ROUND); paint.setPathEffect(new CornerPathEffect(10)); paint.setStrokeWidth(mErasePaintStrokeWidth); paint.setColor(Color.BLUE); Canvas canvas = new Canvas(bmTouchLayer);// 繪制路徑操作 if(isDrawAll){ for(DrawPath db : listDrawPath){ if(db.isErase){ paint.setColor(Color.TRANSPARENT); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); paint.setStrokeWidth(db.paint.getStrokeWidth()); }else{ paint.setColor(Color.BLUE); paint.setXfermode(null); paint.setStrokeWidth(db.paint.getStrokeWidth()); } canvas.drawPath(db.path, paint); } }else{ // 如果不是繪制所有,就只繪制最后一筆 DrawPath db = listDrawPath.get(listDrawPath.size()-1); if(db.isErase){ paint.setColor(Color.TRANSPARENT); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); paint.setStrokeWidth(db.paint.getStrokeWidth()); }else{ paint.setColor(Color.BLUE); paint.setXfermode(null); paint.setStrokeWidth(db.paint.getStrokeWidth()); } canvas.drawPath(db.path, paint); } // 將幕布設置給bmMosaicLayer canvas.setBitmap(bmMosaicLayer); canvas.drawARGB(0, 0, 0, 0); // 將要繪制的 純顏色or馬賽克等圖層繪制上去 canvas.drawBitmap(mEraseMaskBitmap, 0, 0, null); paint.reset(); paint.setAntiAlias(true); // 將bmTouchLayer和圖層層疊 paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); canvas.drawBitmap(bmTouchLayer, 0, 0, paint); paint.setXfermode(null); canvas.save(); // bmTouchLayer.recycle(); }

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容