Android ImageView加载圆形图片且同时绘制圆形图片的外部边缘边线及边框

在Android早期的开发中,如果涉及到圆形图片的处理,往往需要借助于第三方的实现,见附录文章1,2。Android本身并未从SDK层面支持圆形图。但是在后来最新的Android SDK中,增加了对于圆形、圆角图的支持,引入了RoundedBitmapDrawable,RoundedBitmapDrawable的作用是将一个常规图片修剪成圆形或圆角图。RoundedBitmapDrawable的出现,从此在处理简单圆形、圆角图时候简单多了。

但是,对于复杂设计效果的实现,仅仅有一个RoundedBitmapDrawable是不够的,比如,有这样一种设计要求:把一个常规图片修剪成圆形,同时在圆形图边缘部分描出一定宽度的圆形边框,在圆形边框外在描绘出一圈边线,边线与边框之间还要求透明,这种需求,可能要重写ImageView来实现了。

把这个需求分解:

1,首先把常规图片处理成圆形图简单,直接RoundedBitmapDrawable完成。

2,圆形图外部边缘的圆形边框,则需要重写ImageView,在onDraw里面画圆,画一定宽度的圆,但是这一步在计算圆半径时候容易出问题,因为使用getWidth或getHeight这样的方法获得长度除以2算半径时候,整数除法在计算时候要取整,导致圆半径有一定偏差,进而导致画圆的半径不是刚好与圆形图的外部边缘紧密咬合在一起。故需要引入一个平衡因子消除误差。

3,画最外层的圆形边线不用考虑那么复杂,和最内层的圆形边框在半径上拉开一定间距即可。

处理常规图片为圆角的关键代码:

ImageView imageView= (ImageView) findViewById(R.id.imageView);

        RoundedBitmapDrawable circleDrawable = RoundedBitmapDrawableFactory.create(getResources(), BitmapFactory.decodeResource(getResources(), R.drawable.art));
circleDrawable.getPaint().setAntiAlias(true);
circleDrawable.setCircular(true); imageView.setImageDrawable(circleDrawable);

重写ImageView描绘内层的圆形边框以及最外层的圆形边线:

package cn.migu.musicplayer.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.ImageView; /**
* Created by Phil on 2016/7/15.
*/
public class ImageViewWithStroke extends ImageView { //外圈白线和内圈黑线边框之间的间隔。
private int gap = 25; //平衡在计算半径时候因为除以2导致半径计算的误差
private int balance_factor = 2; public ImageViewWithStroke(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
} public ImageViewWithStroke(Context context, AttributeSet attrs) {
super(context, attrs);
} public ImageViewWithStroke(Context context) {
super(context);
} @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas); drawInnerBlackCircle(canvas, 4);
drawOutWhiteCircle(canvas, 1);
} //画最外层的白色边线
private void drawOutWhiteCircle(Canvas canvas, int strokeWidth) {
Paint paint = new Paint();
paint.setColor(Color.WHITE);
paint.setStrokeWidth(strokeWidth);
paint.setStyle(Paint.Style.STROKE);
paint.setAntiAlias(true); int w = this.getPaddingLeft() + this.getPaddingRight();
int x = getWidth() - w;
int r = x / 2; canvas.drawCircle(getWidth() / 2, getHeight() / 2, r + strokeWidth + gap, paint);
} //画最内层的黑色边框
private void drawInnerBlackCircle(Canvas canvas, int strokeWidth) {
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setStrokeWidth(strokeWidth);
paint.setStyle(Paint.Style.STROKE);
paint.setAntiAlias(true); int w = this.getPaddingLeft() + this.getPaddingRight();
float x = getWidth() - w;
float r = x / 2; //半径减去平衡因子是因为在取整时候四舍五入
canvas.drawCircle(getWidth() / 2, getHeight() / 2, (r - balance_factor) + strokeWidth, paint);
}
}

需要处理和加载的目标图片art.jpg:

代码运行结果:

背景的绿色图是在ImageView的background加载一张Android自带的小机器人图。

附录:

1,《Android圆形头像图Circle ImageView》链接地址:http://blog.csdn.net/zhangphil/article/details/44960551 


2,《Android CustomShapeImageView对图片进行各种样式裁剪:圆形、星形、心形、花瓣形等》链接地址:http://blog.csdn.net/zhangphil/article/details/50119921

Android ImageView加载圆形图片且同时绘制圆形图片的外部边缘边线及边框的更多相关文章

  1. Android View加载圆形图片且同时绘制圆形图片的外部边缘边线及边框:LayerDrawable实现

     Android View加载圆形图片且同时绘制圆形图片的外部边缘边线及边框:LayerDrawable实现 LayerDrawable实现的结果和附录文章1,2,3中的layer-list一致. ...

  2. Android Glide加载图片时转换为圆形、圆角、毛玻璃等图片效果

     Android Glide加载图片时转换为圆形.圆角.毛玻璃等图片效果 附录1简单介绍了Android开源的图片加载框架.在实际的开发中,虽然Glide解决了快速加载图片的问题,但还有一个问题悬 ...

  3. Android开发 - ImageView加载Base64编码的图片

    在我们开发应用的过程中,并不是所有情况下都请求图片的URL或者加载本地图片,有时我们需要加载Base64编码的图片.这种情况出现在服务端需要动态生成的图片,比如: 二维码 图形验证码 ... 这些应用 ...

  4. Android 高清加载巨图方案, 拒绝压缩图片

    源地址:http://blog.csdn.net/lmj623565791/article/details/49300989 一.概述 距离上一篇博客有段时间没更新了,主要是最近有些私事导致的,那么就 ...

  5. 演化理解 Android 异步加载图片

    原文:http://www.cnblogs.com/ghj1976/archive/2011/05/06/2038738.html#3018499 在学习"Android异步加载图像小结&q ...

  6. Android框架 加载图片 库 Picasso 的使用简介

    0 说明 现在Android开源库中有许多图片加载框架,本文以picasso为例,总结下开发过程中的一些优化经验,使用的picasso版本如下 compile 'com.squareup.picass ...

  7. 演化理解 Android 异步加载图片(转)

    演化理解 Android 异步加载图片(转)http://www.cnblogs.com/CJzhang/archive/2011/10/20/2218474.html

  8. Android高效加载大图、多图解决方案,有效避免程序内存溢出现象

    好久没有写博客了,今天就先写一个小的关于在Android中加载大图如何避免内存溢出的问题. 后面会写如何使用缓存技术的核心类,android.support.v4.util.LruCache来加载图片 ...

  9. ImageView加载长图(适用不需要缩放的情况)

    此案例适用于加载网络长图且图片的宽和高已知的情况.由于ImageView加载图片有一个4096*4096的限制,所以对于巨长图的加载比较麻烦,需要我们自己去手动处理. 有两种解决方案:第一种就是比较l ...

随机推荐

  1. That Nice Euler Circuit UVALive - 3263 || 欧拉公式

    欧拉定理: 简单多面体的顶点数V.棱数E及面数F间有关系有著名的欧拉公式:V-E+F=2. 设G为任意的连通的平面图,则v-e+f=2,v是G的顶点数,e是G的边数,f是G的面数.(引) 证明(?) ...

  2. composer 加快更新速度

    一.使用代理 set http_proxy=http://127.0.0.1:8087 //Windows export http_proxy=http://127.0.0.1:8087 //linu ...

  3. JEECMS9.3集成dubbo操作记录

    需求描述: 门户及其他应用系统需要查询JEECMS9.3中发布的栏目及数据,而其他系统都是基于dubbo开发的,因此想要将JEECMS9.3中集成dubbo并对外提供内容管理服务. 需求实现: 1.添 ...

  4. 设置UITableViewCell 选中时的背景颜色

    自定义Cell如图 一个View上面放了四个Label 分别连线到.m文件中 @property (weak, nonatomic) IBOutlet UILabel *nameLabel; @pro ...

  5. shell脚本中定义路径变量出现的BUG

    =========================================================================== if 语句中的定义路径变量 引发命令的PATH路 ...

  6. CCF|公共钥匙盒|Java

    import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = ...

  7. Android SDK镜像更新网速慢的解决问题

    通过更换代理解决 Android SDK 在线更新镜像服务器资源:大连东软信息学院镜像服务器地址:http://mirrors.neusoft.edu.cn 端口:80北京化工大学镜像服务器地址:IP ...

  8. Java语法基础-final关键字

    final关键字主要用在三个地方:变量.方法.类. 对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改: 如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一 ...

  9. 分享div、text、Box Shadow(阴影)演示及代码的页面

    附图: 直接上链接:www.css88.com/tool/css3Preview/Box-Shadow.html

  10. linux下svn安装(ALI ECS)

    yum安装svn 搭建和使用SVN 可参考阿里云文档:https://help.aliyun.com/document_detail/52864.html?spm=5176.8208715.110.1 ...