最近研究了下PorterDuffXferMode,也就是图像混合模式。学习了爱哥的自定义View篇的这篇文章:
自定义控件其实很简单1/6。主要学习了关于PorterDuffXfermode的这个部分。具体的关于PorterDuffXfermode的介绍详细,请看爱哥的这篇文章。当看到这个
就手抖的打开了as想试一下这18中模式,自己也画了源图与目标图之后竟然没有像图中显示的效果展示,麻痹的真是头疼,就百度搜,后来在这篇中找到了原因。 PorterDuffXferMode不正确的真正原因)
真尼玛是久旱逢甘霖的感觉。总结了三个原因:
- 必须是两张bitmap才可以使用
- 有可能需要关闭硬件加速
- 两张bitmap的大小尽量一致
然后写了一个自定义的圆角和圆形图:
还是自定义View的老套路:
(一)属性文件:
<resources>
<attr name="radious" format="dimension" />
<attr name="type">
<enum name="circle" value="0" />
<enum name="round" value="1" />
</attr>
<attr name="src" format="reference" />
<declare-styleable name="DefineRoundImage">
<attr name="radious" />
<attr name="type" />
<attr name="src" />
</declare-styleable>
</resources>
(二)onMeasure方法
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
} else {
int disWidth = getPaddingLeft() + getPaddingRight() + mBitamap.getWidth();
if (widthMode == MeasureSpec.AT_MOST) {
width = Math.min(disWidth, widthSize);
} else {
width = disWidth;
}
}
if (heightMode == MeasureSpec.EXACTLY) {
height = heightSize;
} else {
int disHeight = getPaddingBottom() + getPaddingTop() + mBitamap.getHeight();
if (heightMode == MeasureSpec.AT_MOST) {
height = Math.min(disHeight, heightSize);
} else {
height = disHeight;
}
}
setMeasuredDimension(width, height);
}
(三)实现onDraw方法:
@Override
protected void onDraw(Canvas canvas) {
switch (mType) {
case 0://圆
//画一个Dis图
int min = Math.min(width, height);
Bitmap bitmap = Bitmap.createBitmap(min, min, Bitmap.Config.ARGB_8888);
Canvas mCanvas = new Canvas(bitmap);
mCanvas.drawCircle(min / 2, min / 2, min / 2, mPaint);
canvas.drawBitmap(bitmap, 0, 0, mPaint);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
mCanvas.drawBitmap(mBitamap, 0, 0, mPaint);
break;
case 1:
// 带圆角
Bitmap roundBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas roundCanvas = new Canvas(roundBitmap);
roundCanvas.drawRoundRect(new RectF(0, 0, mBitamap.getWidth(), mBitamap.getHeight()), radious, radious, mPaint);
canvas.drawBitmap(roundBitmap, 0, 0, mPaint);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
roundCanvas.drawBitmap(mBitamap, 0, 0, mPaint);
break;
}
}
PorterDuffXferMode的Mode为SRC_IN时会显示两张图片重合的SRC也就是源图的部分。
源码
万恶的周一,进步的周一。