看下效果先

下面有完整的示例代码

使用BitmapShader(着色器)

我们在绘制view 的时候 就是小学上美术课 用水彩笔在本子上画画 使用着色器绘制圆形图片最简单的理解方式 就是把bitmap当做一种颜色 设置给paint ,paint都已经有颜色了 你想让它方了,圆了,扁了 还不是看你心情 canvas调用那个方法咯

实现的大致思路如下:

1. 创建一个类 继承imageView 重写onDraw()

2. 获取到bitmap图片

3. 计算图片的缩放比例 使用矩阵matrix 进行缩放

4. 创建BitmapShader着色器 设置缩放矩阵

5. paint设置着色器 绘制

具体实现 注释也标注的很清楚

   private void shaderCircle(Canvas canvas){
//获取Drawable
Drawable resources=getDrawable();
float scale = 1.0f;//缩放比例
int mRadius=0;//圆的半径
if (resources instanceof BitmapDrawable){
//获取bitmap
Bitmap bitmap=((BitmapDrawable) resources).getBitmap();
if (bitmap==null) return;
// 获取bitmap宽高中的小值
int minBitMap = Math.min(bitmap.getWidth(), bitmap.getHeight());
//取view宽高中的小值 尽量保证图片内容的显示
int minValue=Math.min(getWidth(),getHeight());
//设置半径
mRadius=minValue/2;
//计算缩放比例 一定要*1.0f 因为int之间的计算结果会四舍五入0或1 效果就不美丽了
scale=minValue*1.0f/minBitMap;
//设置缩放比例
matrix.setScale(scale,scale);
/**
* 创建着色器 设置着色模式
* TileMode的取值有三种:
* CLAMP 拉伸 REPEAT 重复 MIRROR 镜像
*/
BitmapShader shader=new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
//设置矩阵
shader.setLocalMatrix(matrix);
paint.setShader(shader);
canvas.drawCircle(mRadius, mRadius, mRadius, paint);
}
}

使用Xfermode 设置图片相交模式

简单说呢 在一张画布上画了两张图片 这两张图的以怎样的方式显示出来 例如:只显示上层图片,只显示下层图片 ,显示两张图的交集部分 等等等

实现思路

  1. 创建一个空bitmap 根据这个bitmap创建一个Canvas
  2. 设置Canvas透明 画一个想要实现的形状
  3. 设置图形相交模式
  4. 获取图片资源 绘制到Canvas

实现代码

 private Bitmap getCircleBitmap(){
Drawable drawable=getDrawable(); if (drawable instanceof BitmapDrawable) {
Paint paint=new Paint();
paint.setAntiAlias(true);
//获取资源图片
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
//创建空位图
Bitmap output=Bitmap.createBitmap(getWidth(),getHeight(),Bitmap.Config.ARGB_8888);
//创建画板
Canvas canvas=new Canvas(output);
//绘制整个画板为透明
canvas.drawColor(Color.TRANSPARENT);
paint.setColor(Color.WHITE);
//绘制圆角图片
if (type==ROUND){
canvas.drawRoundRect(new RectF(0, 0, getWidth(), getHeight()), mRound, mRound,paint);
}else{
//绘制圆形图片 //取view宽高中的小值 尽量保证图片内容的显示
int minValue = Math.min(getWidth(), getHeight());
//设置半径
mRadius = minValue / 2;
canvas.drawCircle(mRadius,mRadius,mRadius,paint);
}
//设置图形相交模式
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); Rect src=new Rect(0,0,bitmap.getWidth(),bitmap.getHeight());
Rect dst=new Rect(0,0,output.getWidth(),output.getHeight());
canvas.drawBitmap(bitmap,src,dst,paint);
return output;
}
return null; }

这个特别经典的图......

PorterDuff.Mode.CLEAR 清除画布上图像
PorterDuff.Mode.SRC 显示上层图像
PorterDuff.Mode.DST 显示下层图像
PorterDuff.Mode.SRC_OVER上下层图像都显示,上层居上显示
PorterDuff.Mode.DST_OVER 上下层都显示,下层居上显示
PorterDuff.Mode.SRC_IN 取两层图像交集部分只显示上层图像
PorterDuff.Mode.DST_IN 取两层图像交集部分,只显示下层图像
PorterDuff.Mode.SRC_OUT 取上层图像非交集部分
PorterDuff.Mode.DST_OUT 取下层图像非交集部分
PorterDuff.Mode.SRC_ATOP 取下层图像非交集部分与上层图像交集部分
PorterDuff.Mode.DST_ATOP 取上层图像非交集部分与下层图像交集部分
PorterDuff.Mode.XOR 取两层图像的非交集部分

参考文档

讲Shader类非常非常屌的帖子

详解Paint的setXfermode

继承ImageVIew完成圆形和圆角图片控件的实现过程(使用着色器)

    <declare-styleable name="CircleImage">
<attr name="imageRound" format="dimension"/>
<attr name="imageType">
<enum name="circle" value="0"/>
<enum name="round" value="1"/>
</attr> </declare-styleable>
public class CircleImage extends ImageView {

    private Matrix matrix;
private Paint paint;
private int mRound;//圆角度数
private int mRadius;//圆的半径
private int type;//控件类型
private final int CIRCLE=0;//圆形
private final int ROUND=1;//圆角 public CircleImage(Context context) {
super(context,null);
} public CircleImage(Context context, AttributeSet attrs) {
super(context, attrs);
matrix=new Matrix();
paint=new Paint();
paint.setAntiAlias(true);
initAttrValues(context,attrs);
} @Override
protected void onDraw(Canvas canvas) {
if (getDrawable() == null) {
return;
}
setShader();
if (type==CIRCLE){
canvas.drawCircle(mRadius, mRadius, mRadius, paint);
}else{
canvas.drawRoundRect(new RectF(0, 0, getWidth(), getHeight()), mRound, mRound,paint);
}
} /**
* 初始化属性集合
* @param context
* @param attrs
*/
private void initAttrValues(Context context, AttributeSet attrs){
TypedArray typedArray=context.obtainStyledAttributes(attrs, R.styleable.CircleImage);
for (int i=0;i<typedArray.getIndexCount();i++){
int index=typedArray.getIndex(i);
switch (index){
case R.styleable.CircleImage_imageRound:
mRound =typedArray.getDimensionPixelSize(index,
(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,10,getResources().getDisplayMetrics()));
break;
case R.styleable.CircleImage_imageType:
type=typedArray.getInt(index,CIRCLE);
break;
}
}
} /**
* 设置着色器
*/
private void setShader() {
//获取Drawable
Drawable resources=getDrawable();
float scale = 1.0f;//缩放比例
if (resources instanceof BitmapDrawable) {
//获取bitmap
Bitmap bitmap = ((BitmapDrawable) resources).getBitmap();
if (bitmap == null) return;
//圆形
if (type==CIRCLE){
// 获取bitmap宽高中的小值
int minBitMap = Math.min(bitmap.getWidth(), bitmap.getHeight());
//取view宽高中的小值 尽量保证图片内容的显示
int minValue = Math.min(getWidth(), getHeight());
//设置半径
mRadius = minValue / 2;
//计算缩放比例 一定要*1.0f 因为int之间的计算结果会四舍五入0或1 效果就不美丽了
scale = minValue * 1.0f / minBitMap;
}else{
//比较view和图片宽高比例大的 要让缩放后的图片大于view
scale = Math.max(getWidth() * 1.0f / bitmap.getWidth(), getHeight()
* 1.0f / bitmap.getHeight());
}
//设置缩放比例
matrix.setScale(scale, scale);
/**
* 创建着色器 设置着色模式
* TileMode的取值有三种:
* CLAMP 拉伸 REPEAT 重复 MIRROR 镜像
*/
BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
//设置矩阵
shader.setLocalMatrix(matrix);
//设置着色
paint.setShader(shader);
}
} /**
* 测试转换效果 没什么卵用 可以删除
* @param event
* @return
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction()==MotionEvent.ACTION_DOWN){
if (type==CIRCLE){
mRound =10;
type=ROUND;
}else{
type=CIRCLE;
}
invalidate();
}
return super.onTouchEvent(event);
}
}

android绘制圆形图片的两种方式的更多相关文章

  1. jQuery 实现图片放大两种方式

    jQuery 实现图片放大两种方式 一.利用css样式表实现,多用于后台显示 1.这种比较简单,利用dom元素的hover实现样式切换 <style> img{ cursor: point ...

  2. Xamarin Android Activity全屏的两种方式

    方式一 直接在Activity的Attribute中定义 如下 在 MainActivity 中 [Activity(Label = "app", MainLauncher = t ...

  3. Android Studio签名打包的两种方式

    签名打包的两种方式: 注:给我们自己开发的app签名,就代表着我自己的版权,以后要进行升级,也必须要使用相同的签名才行.签名就代表着自己的身份(即keystore),多个app可以使用同一个签名. 如 ...

  4. android 发送短信的两种方式,以及接收报告和发送报告

               android发送短信,以及接收报告和发送报告          android中发送短信其实有两种方式,这个和打电话类似,大家可以了解一下:    一.调起系统发短信功能    ...

  5. Android 绘制圆形图片

    经常在项目中,会遇到使用圆形头像. 然而图片往往不是圆形的,我们须要对图片进行处理.以达到圆形图片的效果.这里.我总结了一下经常使用的android圆形图片的绘制的方法. 主要有以下几种方式:1.画布 ...

  6. UIImage加载本地图片的两种方式

    UIImage加载图片方式一般有两种: (1)imagedNamed初始化:默认加载图片成功后会内存中缓存图片,这个方法用一个指定的名字在系统缓存中查找并返回一个图片对象.如果缓存中没有找到相应的图片 ...

  7. Nodejs 传图片的两种方式

    node上传图片第一种方式 1,首先引入模块 "connect-multiparty": "~1.2.5", 在package.json中添加 "co ...

  8. (原创)android中使用相机的两种方式

    在社交类应用或扫描二维码的场合都需要用到手机上的摄像头 在程序中启用这一硬件主要有两类方法 1.发送intent启动系统自带的摄像应用 此应用的AndroidManifest中的intent-filt ...

  9. UIImage创建图片的两种方式的区别

    在工作中经常会遇到添加图片,用哪种方式添加更好呢?请看详解 方法一: UIImage *image = [UIImage imageNamed:@"haha"]; 这种方法创建的图 ...

随机推荐

  1. js学习笔记:操作iframe

    iframe可以说是比较老得话题了,而且网上也基本上在说少用iframe,其原因大致为:堵塞页面加载.安全问题.兼容性问题.搜索引擎抓取不到等等,不过相对于这些缺点,iframe的优点更牛,跨域请求. ...

  2. .Net Core MVC 网站开发(Ninesky) 2.4、添加栏目与异步方法

    在2.3中完成依赖注入后,这次主要实现栏目的添加功能.按照前面思路栏目有三种类型,常规栏目即可以添加子栏目也可以选择是否添加内容,内容又可以分文章或其他类型,所以还要添加一个模块功能.这次主要实现栏目 ...

  3. 如何一步一步用DDD设计一个电商网站(一)—— 先理解核心概念

    一.前言     DDD(领域驱动设计)的一些介绍网上资料很多,这里就不继续描述了.自己使用领域驱动设计摸滚打爬也有2年多的时间,出于对知识的总结和分享,也是对自我理解的一个公开检验,介于博客园这个平 ...

  4. 【趣事】用 JavaScript 对抗 DDOS 攻击 (下)

    上一篇:http://www.cnblogs.com/index-html/p/js-network-firewall.html 对抗 v2 之前的那些奇技淫巧,纯属娱乐而已,并不能撑多久. 但简单. ...

  5. 【社工】NodeJS 应用仓库钓鱼

    前言 城堡总是从内部攻破的.再强大的系统,也得通过人来控制.如果将入侵直接从人这个环节发起,那么再坚固的防线,也都成为摆设. 下面分享一个例子,利用应用仓库,渗透到开发人员的系统中. 应用仓库 应用仓 ...

  6. 数据库优化案例——————某市中心医院HIS系统

    记得在自己学习数据库知识的时候特别喜欢看案例,因为优化的手段是容易掌握的,但是整体的优化思想是很难学会的.这也是为什么自己特别喜欢看案例,今天也开始分享自己做的优化案例. 最近一直很忙,博客产出也少的 ...

  7. 转:聊聊mavenCenter和JCenter

    Gradle支持从maven中央仓库和JCenter上获取构件,那这两者有什么区别呢? maven中央仓库(http://repo1.maven.org/maven2/)是由Sonatype公司提供的 ...

  8. javascript单元测试框架mochajs详解

    关于单元测试的想法 对于一些比较重要的项目,每次更新代码之后总是要自己测好久,担心一旦上线出了问题影响的服务太多,此时就希望能有一个比较规范的测试流程.在github上看到牛逼的javascript开 ...

  9. 如何在网页中提取Email地址

    开博好久了,今天第一次发表技术文档,之前总是将一些好的事例保存在电脑,时间久了找起来也很麻烦,所以还是放在博客里进行归类比较方便,这样也能将自己在学习过程中的一些心得体会分享给大家,也能给需要的人一点 ...

  10. Photoshop将普通照片快速制作二次元漫画风格效果

    今天为大家分享Photoshop将普通照片快速制作二次元漫画风格效果,教程很不错,对于喜欢漫画的朋友可以参考本文,希望能对大家有所帮助! 一提到日本动画电影,大家第一印象肯定是宫崎骏,但是日本除了宫崎 ...