圆角图片

  1 package com.archive.xunji.widgets;
  2 
  3 import android.content.Context;
  4 import android.content.res.TypedArray;
  5 import android.graphics.*;
  6 import android.graphics.drawable.BitmapDrawable;
  7 import android.graphics.drawable.Drawable;
  8 import android.graphics.drawable.NinePatchDrawable;
  9 import android.util.AttributeSet;
 10 import android.widget.ImageView;
 11 import com.archive.xunji.R;
 12 import com.lidroid.xutils.bitmap.core.AsyncDrawable;
 13 
 14 /**
 15  * 圆形ImageView,可设置最多两个宽度不同且颜色不同的圆形边框。
 16  *
 17  *
 18  */
 19 public class RoundImageView extends ImageView {
 20     private int mBorderThickness = 0;
 21     private Context mContext;
 22     private int defaultColor = 0xFFFFFFFF;
 23     // 如果只有其中一个有值,则只画一个圆形边框
 24     private int mBorderOutsideColor = 0;
 25     private int mBorderInsideColor = 0;
 26     // 控件默认长、宽
 27     private int defaultWidth = 0;
 28     private int defaultHeight = 0;
 29 
 30     public RoundImageView(Context context) {
 31         super(context);
 32         mContext = context;
 33     }
 34 
 35     public RoundImageView(Context context, AttributeSet attrs) {
 36         super(context, attrs);
 37         mContext = context;
 38         setCustomAttributes(attrs);
 39     }
 40 
 41     public RoundImageView(Context context, AttributeSet attrs, int defStyle) {
 42         super(context, attrs, defStyle);
 43         mContext = context;
 44         setCustomAttributes(attrs);
 45     }
 46 
 47     private void setCustomAttributes(AttributeSet attrs) {
 48         TypedArray a = mContext.obtainStyledAttributes(attrs,
 49                 R.styleable.roundedimageview);
 50         mBorderThickness = a.getDimensionPixelSize(
 51                 R.styleable.roundedimageview_border_thickness, 0);
 52         mBorderOutsideColor = a
 53                 .getColor(R.styleable.roundedimageview_border_outside_color,
 54                         defaultColor);
 55         mBorderInsideColor = a.getColor(
 56                 R.styleable.roundedimageview_border_inside_color, defaultColor);
 57     }
 58 
 59     @Override
 60     protected void onDraw(Canvas canvas) {
 61         Drawable drawable = getDrawable();
 62         if (drawable == null) {
 63             return;
 64         }
 65 
 66         if (getWidth() == 0 || getHeight() == 0) {
 67             return;
 68         }
 69         this.measure(0, 0);
 70         if (drawable.getClass() == NinePatchDrawable.class)
 71             return;
 72        // Bitmap b = ((BitmapDrawable) drawable).getBitmap();--------------------注意这里解决不支持xutils
 73 
 74         Bitmap b = null;
 75         if(drawable instanceof BitmapDrawable){
 76             b =  ((BitmapDrawable)drawable).getBitmap() ;
 77         }else if(drawable instanceof AsyncDrawable){
 78             b = Bitmap
 79                     .createBitmap(
 80                             getWidth(),
 81                             getHeight(),
 82                             drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
 83                                     : Bitmap.Config.RGB_565);
 84             Canvas canvas1 = new Canvas(b);
 85             // canvas.setBitmap(bitmap);
 86             drawable.setBounds(0, 0, getWidth(),
 87                     getHeight());
 88             drawable.draw(canvas1);
 89         }
 90 
 91 
 92         Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
 93         if (defaultWidth == 0) {
 94             defaultWidth = getWidth();
 95 
 96         }
 97         if (defaultHeight == 0) {
 98             defaultHeight = getHeight();
 99         }
100         // 保证重新读取图片后不会因为图片大小而改变控件宽、高的大小(针对宽、高为wrap_content布局的imageview,但会导致margin无效)
101         // if (defaultWidth != 0 && defaultHeight != 0) {
102         // LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
103         // defaultWidth, defaultHeight);
104         // setLayoutParams(params);
105         // }
106         int radius = 0;
107         if (mBorderInsideColor != defaultColor
108                 && mBorderOutsideColor != defaultColor) {// 定义画两个边框,分别为外圆边框和内圆边框
109             radius = (defaultWidth < defaultHeight ? defaultWidth
110                     : defaultHeight) / 2 - 2 * mBorderThickness;
111             // 画内圆
112             drawCircleBorder(canvas, radius + mBorderThickness / 2,
113                     mBorderInsideColor);
114             // 画外圆
115             drawCircleBorder(canvas, radius + mBorderThickness
116                     + mBorderThickness / 2, mBorderOutsideColor);
117         } else if (mBorderInsideColor != defaultColor
118                 && mBorderOutsideColor == defaultColor) {// 定义画一个边框
119             radius = (defaultWidth < defaultHeight ? defaultWidth
120                     : defaultHeight) / 2 - mBorderThickness;
121             drawCircleBorder(canvas, radius + mBorderThickness / 2,
122                     mBorderInsideColor);
123         } else if (mBorderInsideColor == defaultColor
124                 && mBorderOutsideColor != defaultColor) {// 定义画一个边框
125             radius = (defaultWidth < defaultHeight ? defaultWidth
126                     : defaultHeight) / 2 - mBorderThickness;
127             drawCircleBorder(canvas, radius + mBorderThickness / 2,
128                     mBorderOutsideColor);
129         } else {// 没有边框
130             radius = (defaultWidth < defaultHeight ? defaultWidth
131                     : defaultHeight) / 2;
132         }
133         Bitmap roundBitmap = getCroppedRoundBitmap(bitmap, radius);
134         canvas.drawBitmap(roundBitmap, defaultWidth / 2 - radius, defaultHeight
135                 / 2 - radius, null);
136     }
137 
138     /**
139      * 获取裁剪后的圆形图片
140      *
141      * @param radius
142      *            半径
143      */
144     public Bitmap getCroppedRoundBitmap(Bitmap bmp, int radius) {
145         Bitmap scaledSrcBmp;
146         int diameter = radius * 2;
147 
148         // 为了防止宽高不相等,造成圆形图片变形,因此截取长方形中处于中间位置最大的正方形图片
149         int bmpWidth = bmp.getWidth();
150         int bmpHeight = bmp.getHeight();
151         int squareWidth = 0, squareHeight = 0;
152         int x = 0, y = 0;
153         Bitmap squareBitmap;
154         if (bmpHeight > bmpWidth) {// 高大于宽
155             squareWidth = squareHeight = bmpWidth;
156             x = 0;
157             y = (bmpHeight - bmpWidth) / 2;
158             // 截取正方形图片
159             squareBitmap = Bitmap.createBitmap(bmp, x, y, squareWidth,
160                     squareHeight);
161         } else if (bmpHeight < bmpWidth) {// 宽大于高
162             squareWidth = squareHeight = bmpHeight;
163             x = (bmpWidth - bmpHeight) / 2;
164             y = 0;
165             squareBitmap = Bitmap.createBitmap(bmp, x, y, squareWidth,
166                     squareHeight);
167         } else {
168             squareBitmap = bmp;
169         }
170 
171         if (squareBitmap.getWidth() != diameter
172                 || squareBitmap.getHeight() != diameter) {
173             scaledSrcBmp = Bitmap.createScaledBitmap(squareBitmap, diameter,
174                     diameter, true);
175 
176         } else {
177             scaledSrcBmp = squareBitmap;
178         }
179         Bitmap output = Bitmap.createBitmap(scaledSrcBmp.getWidth(),
180                 scaledSrcBmp.getHeight(), Bitmap.Config.ARGB_8888);
181         Canvas canvas = new Canvas(output);
182 
183         Paint paint = new Paint();
184         Rect rect = new Rect(0, 0, scaledSrcBmp.getWidth(),
185                 scaledSrcBmp.getHeight());
186 
187         paint.setAntiAlias(true);
188         paint.setFilterBitmap(true);
189         paint.setDither(true);
190         canvas.drawARGB(0, 0, 0, 0);
191         canvas.drawCircle(scaledSrcBmp.getWidth() / 2,
192                 scaledSrcBmp.getHeight() / 2, scaledSrcBmp.getWidth() / 2,
193                 paint);
194         paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
195         canvas.drawBitmap(scaledSrcBmp, rect, rect, paint);
196         // bitmap回收(recycle导致在布局文件XML看不到效果)
197         // bmp.recycle();
198         // squareBitmap.recycle();
199         // scaledSrcBmp.recycle();
200         bmp = null;
201         squareBitmap = null;
202         scaledSrcBmp = null;
203         return output;
204     }
205 
206     /**
207      * 边缘画圆
208      */
209     private void drawCircleBorder(Canvas canvas, int radius, int color) {
210         Paint paint = new Paint();
211         /* 去锯齿 */
212         paint.setAntiAlias(true);
213         paint.setFilterBitmap(true);
214         paint.setDither(true);
215         paint.setColor(color);
216         /* 设置paint的 style 为STROKE:空心 */
217         paint.setStyle(Paint.Style.STROKE);
218         /* 设置paint的外框宽度 */
219         paint.setStrokeWidth(mBorderThickness);
220         canvas.drawCircle(defaultWidth / 2, defaultHeight / 2, radius, paint);
221     }
222 
223 }
RoundImage
1 <?xml version="1.0" encoding="utf-8"?>
2 <resources>
3     <declare-styleable name="roundedimageview">
4         <attr name="border_thickness" format="dimension" />
5         <attr name="border_inside_color" format="color" />
6         <attr name="border_outside_color" format="color"></attr>
7     </declare-styleable>
8 </resources>
styleable.xml
<com.archive.xunji.widgets.RoundImageView
           android:id="@+id/iv_touxiang_guangchangfragment"
           android:layout_alignBottom="@id/tv_username_guangchangfragment"
           android:layout_toLeftOf="@id/tv_username_guangchangfragment"
           android:layout_marginRight="5dp"
           android:layout_width="30dp"
           android:layout_height="30dp"
           android:src="@mipmap/ic_launcher"
           />

 圆形图片最主要的方法   paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));

意思是取两个元素在画布上的交集然后取上层部分显示  如此将圆形图片展示出来

原文地址:https://www.cnblogs.com/bimingcong/p/4954457.html