android 六棱形分析图,Android自定义View_菱形图片

yEJvua.png 自定义菱形图片.png

前言

在实际项目中,用户头像,音乐专辑都有可能用到圆形,菱形等无规则图像,需要自己自定义View实现相应的功能。

思路

需求:制作圆角菱形的图片

思路:

1、绘制出圆角矩形的遮罩层;

2、将矩形旋转45°;

3、使用画笔的PorterDuffXfermode的SRC_IN属性;

4、将图片绘制遮罩层上。

PorterDuffXfermode

PorterDuffXfermode在网上有许多讲解它的文章,这里只讲解最常用的两种模式SRC_IN和DST_IN。

SRC_IN:【本文所用的模式】显示底层图像和上方图像的相交区域,且显示的是上方图像。如图所示,先绘制出黄色的底层图像,再绘制出蓝色的图像,设置的模式为SRC_IN,则显示的是两张图像相交的扇形区域,且为上层蓝色图像。

63Ijey.png Picture.png

Ezy2Ef.png SRC_IN.png

DST_IN:显示底层图像和上方图像的相交区域,且

显示的是底层图像。如图所示,先绘制出黄色的底层图像,再绘制出蓝色的图像,设置的模式为DST_IN,则显示的是两张图像相交的扇形区域,且为底层黄色图像。

fARj63.png DST_IN.png

实现

1、根据图片的大小绘制出圆角矩形的遮罩层;

// 创建图片

mImageBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.picture);

// 获取图片的宽高

mWidth = mImageBitmap.getWidth();

mHeight = mImageBitmap.getHeight();

mMaskBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);

Canvas maskCanvas = new Canvas(mMaskBitmap);

mPaint = new Paint();

mPaint.setColor(Color.YELLOW);

mPaint.setAntiAlias(true);

// 画布先平移后旋转

maskCanvas.translate(mWidth / 2, 0);

maskCanvas.rotate(45);

int rectSize = (int) (mWidth / 2 / Math.sin(Math.toRadians(45)));

// 绘制圆角矩形

maskCanvas.drawRoundRect(0, 0, rectSize, rectSize, 50, 50, mPaint);

2、设置两张图像的显示模式为SRC_IN;

mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));

3、这里需要注意的是因为使用的是同一个画布Canvas,在绘制圆角矩形时已经将画布旋转45°并且平移,这里就需要将画布旋转平移回到初始状态,不然图片就会跟着旋转,就会如下图所示。

zM3eEf.png RotatePicture.png

// 画布先旋转后平移,防止图片也跟着旋转

maskCanvas.rotate(-45);

maskCanvas.translate(-mWidth / 2, 0);

4、绘制上层图片

maskCanvas.drawBitmap(mImageBitmap, 0, 0, mPaint);

5、最后在onDraw方法中绘制出最后的图片;

@Override

protected void onDraw(Canvas canvas) {

canvas.drawBitmap(getBitmap(), 0, 0, null);

}

总结

设计无规则图形,方法大同小异,可使用PorterDuffXfermode的不同模式实现不同的效果。需要注意的是由于底层和上层的图像都是同一个Canvas绘制,绘制底层时已经改变了方向,后面绘制上层时需要回复到初始状态。另外也可以另写方法创建新的Canvas绘制上层图像,就不必恢复。

源码

public class CustomDiamondImage extends View {

private Paint mPaint;

private int mWidth;

private int mHeight;

private Bitmap mMaskBitmap;

private Bitmap mImageBitmap;

public CustomDiamondImage(Context context) {

super(context);

}

public CustomDiamondImage(Context context, AttributeSet attrs) {

super(context, attrs);

}

@Override

protected void onDraw(Canvas canvas) {

canvas.drawBitmap(getBitmap(), 0, 0, null);

}

private Bitmap getBitmap() {

// 创建图片

mImageBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.picture);

// 获取图片的宽高

mWidth = mImageBitmap.getWidth();

mHeight = mImageBitmap.getHeight();

mMaskBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);

Canvas maskCanvas = new Canvas(mMaskBitmap);

mPaint = new Paint();

mPaint.setColor(Color.YELLOW);

mPaint.setAntiAlias(true);

// 画布先平移后旋转

maskCanvas.translate(mWidth / 2, 0);

maskCanvas.rotate(45);

int rectSize = (int) (mWidth / 2 / Math.sin(Math.toRadians(45)));

// 绘制圆角矩形

maskCanvas.drawRoundRect(0, 0, rectSize, rectSize, 50, 50, mPaint);

// 设置混合显示模式为SRC_IN

mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));

// 画布先旋转后平移,防止图片也跟着旋转

maskCanvas.rotate(-45);

maskCanvas.translate(-mWidth / 2, 0);

maskCanvas.drawBitmap(mImageBitmap, 0, 0, mPaint);

return mMaskBitmap;

}

}

欢迎关注我的公众号:小猿说,大家一起学习交流。

jInQvu.jpg 公众号

作者:SGoofy

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值