先來個效果樣式,實現效果如下圖所示:
簡單說效果主要是對圖片做 mask(遮罩)實現劳澄,然后再實現可書寫的效果泵琳。下面步入正題。
1.PorterDuffXfermode
做遮罩需要使用到 PorterDuffXfermode 的相關用法几颜,下圖來自網上:
黃色的圓是DST下層,先進行繪制
藍色的矩形是SRC上層讯屈,后進行繪制
由圖可看出蛋哭,PorterDuffXfermode 主要用于兩種圖型相互組合后形成所要的效果,使用方式就是調用Paint對象的setXfermode(PorterDuffXfermode model)方法即可耻煤。
pain.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
現在我們要實現效果圖所展示的遮罩效果具壮。
首先准颓,初始化 paint
和 DST
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
int centerX = w/2;
int centerY = h/2;
int offset = width/4;
srcRect = new RectF(centerX-offset, centerY-offset, centerX+offset, centerY+offset);
dstRect = new RectF(centerX-offset, centerY-offset, centerX+offset, centerY+offset);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG ;
mPaint.setColor(Color.GRAY);
dstBmp = BitmapFactory.decodeResource(getResources(), R.mipmap.dst_image);
PorterDuff.Mode mPorterDuffMode = PorterDuff.Mode.SRC_IN;
mXfermode = new PorterDuffXfermode(mPorterDuffMode)哈蝇;
}
代碼很簡單,就是簡單的初始化變量攘已,設置繪制區(qū)域范圍炮赦。
然后就是 開始繪制:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//1. 為畫布設置背景色
canvas.drawColor(Color.WHITE);
/** 2. 畫布背景不是透明的,所以需要 saveLayer 方法為 canvas 創(chuàng)建一個新的透明圖層样勃,
也就是所謂的 offscreen 離屏渲染方式, 簡單來說就是新啟圖層繪制吠勘,繪制結束(restore)之后性芬,再繪制到上一個圖層
**/
int saveCount = canvas.saveLayer(srcRect, mPaint, Canvas.ALL_SAVE_FLAG);
//3. 將 DST 繪制到新的圖層上面
canvas.drawBitmap(dstBmp, null, dstRect, mPaint);
//4. 設置畫筆混合模式和顏色,繪制 SRC
mPaint.setXfermode(mXfermode);
mPaint.setColor(Color.GRAY);
canvas.drawRect(srcRect,mPaint);
mPaint.setXfermode(null);
// 5. 繪制結束剧防,將繪制的新圖層繪制到圖層
canvas.restoreToCount(saveCount);
}
注釋寫的比較詳細植锉,就不再贅述了。下面實現書寫控制峭拘。
2.手勢交互
定義一個 Paint
實現書寫功能:
drawPaint = new Paint();
drawPaint.setAntiAlias(true);
//畫筆粗細
drawPaint.setStrokeWidth(20);
//畫筆圓角
drawPaint.setStrokeCap(Paint.Cap.ROUND);
drawPaint.setStyle(Paint.Style.STROKE);
//設置混合模式俊庇,參照上圖這地方設置為 DST_OUT
drawPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
復寫 View 的 onTouchEvent 代碼如下:
@Override
public boolean onTouchEvent(MotionEvent event)
{
int action = event.getAction();
int x = (int) event.getX();
int y = (int) event.getY();
switch (action)
{
case MotionEvent.ACTION_DOWN:
mLastX = x;
mLastY = y;
path.moveTo(mLastX, mLastY);
break;
case MotionEvent.ACTION_MOVE:
int dx = Math.abs(x - mLastX);
int dy = Math.abs(y - mLastY);
//滑動距離大于5個像素設置 path,然后重繪鸡挠。
if (dx > 5 || dy > 5)
path.lineTo(x, y);
mLastX = x;
mLastY = y;
break;
}
//重繪
invalidate();
return true;
}
然后修改 ondraw()
方法辉饱,在繪制結束前,繪制 path
路徑拣展,最后修改后為:
//1. 為畫布設置背景色
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(dstBmp, null, dstRect, mPaint);
...
canvas.drawPath(path,drawPaint);
// 5. 繪制結束彭沼,將繪制的新圖層繪制到圖層
canvas.restoreToCount(saveCount);
以上就是簡單的實現過程,有錯誤备埃,請指出姓惑。