开头我们来看 ProterDuff 这个词 。
好神奇的单词,完全不知道什么意思对不对(有木有),上网一搜原来是关于2D图像组合的一种理论。
这是豆瓣上的解释:http://www.douban.com/note/143111853/
那么我们为什么要组合2D图形呢?我们先来看一组图:
这是桌面应用程序在触摸和拖动图标时候的状态,图1中的白色围绕着bitmap的边缘,图2也是。找到桌面源码中的HolographicOutlineHelper.java查看,原来是用到了ProterDuff.Mode组合出来的图形。当然还有大量的计算。下面介绍一下ProterDuff是如何来组合图形的
PorterDuff.Mode
java.lang.Object | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
↳ | java.lang.Enum<android.graphics.PorterDuff.Mode> | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
↳ | android.graphics.PorterDuff.Mode Summary
|
所绘制不会提交到画布上。
2.PorterDuff.Mode.SRC
3.PorterDuff.Mode.DST
4.PorterDuff.Mode.SRC_OVER
5.PorterDuff.Mode.DST_OVER
6.PorterDuff.Mode.SRC_IN
7.PorterDuff.Mode.DST_IN
8.PorterDuff.Mode.SRC_OUT
9.PorterDuff.Mode.DST_OUT
10.PorterDuff.Mode.SRC_ATOP
11.PorterDuff.Mode.DST_ATOP
12.PorterDuff.Mode.XOR
13.PorterDuff.Mode.DARKEN
14.PorterDuff.Mode.LIGHTEN
15.PorterDuff.Mode.MULTIPLY
16.PorterDuff.Mode.SCREEN
public class DuffView extends View {private Bitmap mSrcB;private Bitmap mDstB;private Shader mBG;// 文档说了是枚举类,共有16个private static final Xfermode[] sModes = { new PorterDuffXfermode(PorterDuff.Mode.CLEAR),new PorterDuffXfermode(PorterDuff.Mode.SRC), new PorterDuffXfermode(PorterDuff.Mode.DST),new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER), new PorterDuffXfermode(PorterDuff.Mode.DST_OVER),new PorterDuffXfermode(PorterDuff.Mode.SRC_IN), new PorterDuffXfermode(PorterDuff.Mode.DST_IN),new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT), new PorterDuffXfermode(PorterDuff.Mode.DST_OUT),new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP), new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP),new PorterDuffXfermode(PorterDuff.Mode.XOR), new PorterDuffXfermode(PorterDuff.Mode.DARKEN),new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN), new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY),new PorterDuffXfermode(PorterDuff.Mode.SCREEN) };public DuffView(Context context) {super(context);}public DuffView(Context context, AttributeSet attrs) {super(context, attrs);init();}public DuffView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}// 初始化private void init() {mSrcB = makeSrc(400, 400);mDstB = makeDst(400, 400);Bitmap bitmap = Bitmap.createBitmap(new int[] { 0xFFFFFFFF, 0xFFCCCCCC, 0xFFCCCCCC, 0xFFFFFFFF }, 2, 2,Bitmap.Config.RGB_565);mBG = new BitmapShader(bitmap, TileMode.REPEAT, TileMode.REPEAT);Matrix m = new Matrix();m.setScale(6, 6);mBG.setLocalMatrix(m);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.drawColor(Color.WHITE);Paint paint = new Paint();paint.setFilterBitmap(false);canvas.translate(35, 35);paint.setStyle(Style.STROKE);paint.setShader(null);canvas.drawRect(0, 0, 400, 400, paint);// shaderpaint.setStyle(Style.FILL);paint.setShader(mBG);canvas.drawRect(0, 0, 400, 400, paint);int sc = canvas.saveLayer(0, 0, 400, 400, null, Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG| Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.FULL_COLOR_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG);canvas.drawBitmap(mDstB, 0, 0, paint);// 组合图形最关键的地方就在这里// paint.setXfermode(sModes[0]);canvas.drawBitmap(mSrcB, 0, 0, paint);canvas.restoreToCount(sc);}// 画圆static Bitmap makeDst(int w, int h) {Bitmap bitmap = Bitmap.createBitmap(w, h, Config.ARGB_8888);Canvas canvas = new Canvas(bitmap);Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);p.setColor(0xFFFFCC44);p.setColor(Color.RED);canvas.drawCircle(w / 2, h / 2, w / 3, p);return bitmap;}// 画方static Bitmap makeSrc(int w, int h) {Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);Canvas c = new Canvas(bm);Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);p.setColor(0xFF66AAFF);c.drawRect(w / 2, h / 2, w - 20, h - 20, p);return bm;}}