最近在做毕业设计,想有一个功能和QQ一样可以裁剪头像并设置圆形头像,额,这是设计狮的一种潮流。
而纵观现在主流的APP,只要有用户系统这个功能,这个需求一般都是在(bu)劫(de)难(bu)逃(xue)!
图片裁剪实现方式有两种,一种是利用系统自带的裁剪工具,一种是使用开源工具Cropper。本节就为大家带来如何使用系统自带的裁剪工具进行图片裁剪~
还是先来个简单的运行图。(Ps,本人还没结婚,照片是我表哥~)
额,简单说下,我待会会把代码写成小demo分享给大家,在文章末尾会附上github链接,需要的可以自行下载~
下面来简单分析一下实现思路,我们首先照片肯定可以通过拍照和从相册选取,这个都可以向系统发送特定的Intent,响应对应的系统程序,然后在onActivityResult里面,获取我们的数据即可。而在onActivityResult里面,我们可以获取到两种形式的数据,Bitmap and uri。一般情况下我们是不会选择Bitmap的,因为大家都知道我们的手机里面的照片都太大了~强行使用bitmap,我只能说你,屌屌屌,sorry,我说的不是666,是傻屌的意思!
哈哈哈,让我爆粗口,我原本是拒绝的~只是希望警醒在看文章的你,那么就用uri吧~
那么然后呢?当然是对它做裁剪,完成后把这个裁剪后的bitmap对象设置给ImageView,保存起来,上传到服务器即可。
大致了解了流程,那么我们直接看代码吧~
先看看我们的圆形Image吧,我这个有点乱,因为考虑了很多我毕设的逻辑,所以做了一些修正,这个圆形Image相信网上会很多。
1 package com.example.nanchen.cropimagetest; android.content.Context; 4 import android.content.res.TypedArray; 5 import android.graphics.Bitmap; 6 import android.graphics.Bitmap.Config; 7 import android.graphics.Canvas; 8 import android.graphics.Color; 9 import android.graphics.ColorMatrix; 10 import android.graphics.ColorMatrixColorFilter; 11 import android.graphics.Paint; 12 import android.graphics.PorterDuff.Mode; 13 import android.graphics.PorterDuffXfermode; 14 import android.graphics.Rect; 15 import android.graphics.RectF; 16 import android.util.AttributeSet; 17 import android.view.MotionEvent; 18 import android.view.View; 19 import android.widget.ImageView; nanchen 23 * @fileName CropImageTest 24 * @packageName com.example.nanchen.cropimagetest 25 * @date 2016/10/13 15:09 RoundImageView extends ImageView { * 圆形ImageView,可设置最多两个宽度不同且颜色不同的圆形边框。 32 * Alan imageview_level { level0 = 0; level1 = 1; level2 = 2; level3 = 3; level4 = 4; 42 } Context mContext; circleColor = Color.WHITE; circleWidth = 0; mLevel = imageview_level.level1; setLevel(int level) { 51 mLevel = level; 52 } 53 public RoundImageView(Context context) { 54 super(context); 55 mContext = context; 56 } RoundImageView(Context context, AttributeSet attrs) { 59 super(context, attrs); 60 mContext = context; 61 setCustomAttributes(attrs); 62 } RoundImageView(Context context, AttributeSet attrs, int defStyle) { 65 super(context, attrs, defStyle); 66 mContext = context; 67 setCustomAttributes(attrs); 68 } setCustomAttributes(AttributeSet attrs) { 71 TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.roundedimageview); 72 int width = a.getDimensionPixelSize(R.styleable.roundedimageview_border_thickness, 0); 73 setPadding(width, width, width, width); 74 mLevel = a.getInt(R.styleable.roundedimageview_image_mode, imageview_level.level1); 75 circleColor = a.getColor(R.styleable.roundedimageview_border_color, circleColor); 76 } @Override setImageBitmap(Bitmap bm) { 81 switch (this.mLevel) { 82 case imageview_level.level1 : 83 bm = RoundBitmap(bm); 84 case imageview_level.level2 : 85 if ((getPaddingLeft() == getPaddingRight()) && (getPaddingLeft() == getPaddingBottom()) 86 && (getPaddingLeft() == getPaddingTop())) { 87 this.circleWidth = getPaddingLeft(); 88 bm = RoundBitmap(bm); 89 } 90 break; 91 case imageview_level.level3 : 92 bm = ChamferBitmap(bm); 93 break; 94 case imageview_level.level4: 95 if ((getPaddingLeft() == getPaddingRight()) && (getPaddingLeft() == getPaddingBottom()) 96 && (getPaddingLeft() == getPaddingTop())) { 97 this.circleWidth = getPaddingLeft(); 98 bm = RoundBitmap(bm); 99 } 100 break; 101 default : 102 break; 103 } 104 super.setImageBitmap(bm); 105 } 106 107 @Override onDraw(Canvas canvas) { 109 switch (this.mLevel) { 110 case imageview_level.level2: 111 if (circleWidth > 0) { 112 drawCircleBorder(canvas, (getWidth() - this.circleWidth*2 + circleWidth) / 2, this.circleColor, getWidth(), 113 getHeight(), this.circleWidth); 114 } 115 break; 116 case imageview_level.level4: 117 if (circleWidth > 0){ 118 int paddingwidth = circleWidth; 119 120 drawCircleBorder(canvas, (getWidth()-paddingwidth*2 +circleWidth /2) / 2, this.circleColor, getWidth(), 121 getHeight(), this.circleWidth /2,Color.DKGRAY); tempwidth = circleWidth /2; 124 drawCircleBorder(canvas, (getWidth()-paddingwidth*2 +tempwidth) / 2, this.circleColor, getWidth(), 125 getHeight(), tempwidth,Color.DKGRAY); 126 127 } 128 break; 129 default: 130 break; 131 } 132 super.onDraw(canvas); 133 } * bitmap切成圆形 137 * bitmap 传入Bitmap对象 Bitmap RoundBitmap(Bitmap bitmap) { 142 Bitmap resultBitmap = null; 143 Canvas canvas = null; 144 int width = bitmap.getWidth(); 145 int height = bitmap.getHeight(); 146 float roundPx; 147 float left, top, right, bottom, dst_left, dst_top, dst_right, dst_bottom; 148 if (width <= height) { 149 roundPx = width / 2; 150 top = 0; 151 bottom = width; 152 left = 0; 153 right = width; 154 height = width; 155 dst_left = 0; 156 dst_top = 0; 157 dst_right = width; 158 dst_bottom = width; 159 } else { 160 roundPx = height / 2; 161 float clip = (width - height) / 2; 162 left = clip; 163 right = width - clip; 164 top = 0; 165 bottom = height; 166 width = height; 167 dst_left = 0; 168 dst_top = 0; 169 dst_right = height; 170 dst_bottom = height; 171 } 172 if (width <= 0) { 173 width = 1; 174 } 175 if (height <= 0) { 176 height = 1; 177 } { 180 resultBitmap = Bitmap.createBitmap(width, height, Config.ARGB_4444); 181 } catch (Throwable e) { 182 e.printStackTrace(); 183 } { 186 canvas = new Canvas(resultBitmap); 187 } catch (Throwable e) { 188 e.printStackTrace(); 189 } color = Color.RED; 192 final Paint paint = new Paint(); 193 final Rect src = new Rect((int) left, (int) top, (int) right, (int) bottom); 194 final Rect dst = new Rect((int) dst_left, (int) dst_top, (int) dst_right, (int) dst_bottom); 195 final RectF rectF = new RectF(dst); 196 paint.setAntiAlias(true); 197 canvas.drawARGB(0, 0, 0, 0); canvas.drawRoundRect(rectF, roundPx, roundPx, paint); 200 paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); 201 canvas.drawBitmap(bitmap, src, dst, paint); 202 return resultBitmap; 203 } * bitmap倒角 207 * bitmap 传入Bitmap对象 Bitmap ChamferBitmap(Bitmap bitmap) { 212 Bitmap resultBitmap = null; 213 Canvas canvas = null; 214 int width = bitmap.getWidth(); 215 int height = bitmap.getHeight(); 216 float roundPx; 217 float left, top, right, bottom, dst_left, dst_top, dst_right, dst_bottom; 218 if (width <= height) { top = 0; 221 bottom = width; 222 left = 0; 223 right = width; 224 height = width; 225 dst_left = 0; 226 dst_top = 0; 227 dst_right = width; 228 dst_bottom = width; 229 } else { clip = (width - height) / 2; 232 left = clip; 233 right = width - clip; 234 top = 0; 235 bottom = height; 236 width = height; 237 dst_left = 0; 238 dst_top = 0; 239 dst_right = height; 240 dst_bottom = height; 241 } 242 if (width <= 0) { 243 width = 1; 244 } 245 if (height <= 0) { 246 height = 1; 247 } { 250 resultBitmap = Bitmap.createBitmap(width, height, Config.ARGB_4444); 251 } catch (Throwable e) { 252 e.printStackTrace(); 253 } { 256 canvas = new Canvas(resultBitmap); 257 } catch (Throwable e) { 258 e.printStackTrace(); 259 } color = Color.RED; 262 final Paint paint = new Paint(); 263 final Rect src = new Rect((int) left, (int) top, (int) right, (int) bottom); 264 final Rect dst = new Rect((int) dst_left, (int) dst_top, (int) dst_right, (int) dst_bottom); 265 final RectF rectF = new RectF(dst); 266 paint.setAntiAlias(true); 267 canvas.drawARGB(0, 0, 0, 0); canvas.drawRoundRect(rectF, roundPx, roundPx, paint); 270 paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); 271 canvas.drawBitmap(bitmap, src, dst, paint); 272 return resultBitmap; 273 } * 画布画圆 drawCircleBorder(Canvas canvas, int radius, int color, int width, int height, int circleWidth) { 279 Paint paint = new Paint(); paint.setAntiAlias(true); 282 paint.setFilterBitmap(true); 283 paint.setDither(true); 284 paint.setColor(color); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(circleWidth); 289 canvas.drawCircle(width / 2, height / 2, radius, paint); 290 } drawCircleBorder(Canvas canvas, int radius, int color, int width, int height, int circleWidth,int shadowcolor){ canvas.rotate(45,width / 2, height / 2); Paint paint = new Paint(); ( { 300 canvas.drawCircle(width/2+i, height / 2, radius+2, paint); 301 } 302 canvas.restore(); 303 304 paint = new Paint(); paint.setAntiAlias(true); 307 paint.setFilterBitmap(true); 308 paint.setDither(true); 309 paint.setColor(color); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(circleWidth); canvas.drawCircle(width / 2, height / 2, radius, paint); 315 } setCircleWidth(int padding) { 318 setPadding(padding, padding, padding, padding); 319 } getCircleColor() { 322 return circleColor; 323 } setCircleColor(int circleColor) { 326 this.circleColor = circleColor; 327 } getCircleWidth() { .circleWidth; 332 } OnTouchListener onTouchListener = new OnTouchListener() { 335 @Override onTouch(View view, MotionEvent event) { 337 switch (event.getAction()) { 338 case MotionEvent.ACTION_UP: 339 changeLight((ImageView) view, 0); ; 342 case MotionEvent.ACTION_DOWN: 343 changeLight((ImageView) view, -60); 344 break; 345 case MotionEvent.ACTION_MOVE: ; 348 case MotionEvent.ACTION_CANCEL: 349 changeLight((ImageView) view, 0); 350 break; 351 default: 352 break; 353 } ; 355 } 356 }; setColorFilter(boolean value){ 359 if(value){ 360 setOnTouchListener(onTouchListener); 361 }else{ 362 setOnTouchListener(null); 363 } 364 } changeLight(ImageView imageview, int brightness) { 367 ColorMatrix matrix = new ColorMatrix(); 368 matrix.set(new float[] { 1, 0, 0, 0, brightness, 0, 1, 0, 0, brightness, 0, 0, 1, 0, brightness, 0, 0, 0, 1, 0 }); 369 imageview.setColorFilter(new ColorMatrixColorFilter(matrix)); 370 } * 根据手机的分辨率从 dp 的单位 转成为 px(像素) dip2px(Context context, float dpValue) { scale = context.getApplicationContext().getResources().getDisplayMetrics().density; 377 return (int) (dpValue * scale + 0.5f); 378 } }
自定义一个仿IOS的弹出框