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. Poj 3189 Steady Cow Assignment (多重匹配)

    题目链接: Poj 3189 Steady Cow Assignment 题目描述: 有n头奶牛,m个棚,每个奶牛对每个棚都有一个喜爱程度.当然啦,棚子也是有脾气的,并不是奶牛想住进来就住进来,超出棚 ...

  2. leaflet在地图上加载本地图片

    <link href="~/Scripts/Leaflet/leaflet.css" rel="stylesheet" /><script s ...

  3. PHP 官方说明

    http://php.net/manual/en/mysqli.affected-rows.php The above examples will output: Affected rows (INS ...

  4. 树莓派 离线安装 apt-get offline

    有网络的地方 sudo cp /var/cache/apt/archives/YOUR_PACK_NAME ~/swap/deb/ 没网络的地方 sudo dpkg -i ~/swap/deb/*

  5. [转]ASP.NET MVC 3 Application Upgrader

    本文转自:http://aspnet.codeplex.com/releases/view/59008 Recommended Download      ASP.NET MVC 3 Applicat ...

  6. Oracle函数大全下载

    Oracle函数大全下载 是一个压缩包,里面是一个chm格式的帮助文档,很实用.

  7. 《基于Node.js实现简易聊天室系列之引言》

    简述:这个聊天室是基于Node.js实现的,完成了基本的实时通信功能.在此之前,对node.js和mongodb一无所知,但是通过翻阅博客,自己动手基本达到了预期的效果.技术,不应该是闭门造车,而是学 ...

  8. 维控PLC与电流变送器modbus通讯获取电流变送器数据

    2018-09-2319:28:01 今天本来要用单片机来做这个项目的,但是失败了.... 所以我又拿出了PLC来搞,也是相当之复杂,查了很多资料终于做出而来了. 今天还有事,赶紧临时备份总结一波

  9. oracle 代码块

    oracle 的代码块模板 declare --声明变量 begin --执行业务逻辑 exception --异常处理 end; --结束 注意:代码块每个sql语句结束都要加冒号 eg: --pl ...

  10. java内存查看与分析

    业界有很多强大的java profile的工具,比如Jporfiler,yourkit,这些收费的东西我就不想说了,想说的是,其实java自己就提供了很多内存监控的小工具,下面列举的工具只是一小部分, ...