Bitmap 搓圆
来源:互联网 发布:知乎日报 大误 编辑:程序博客网 时间:2024/04/29 09:45
一般要做正圆形图片,只能是正方形的基础上才能实现,否则就变成椭圆了,下面说说如何使长方形的图片生成正圆形图片
废话不多说,没图没真相,先上图吧:
原图:
由于图片是长方形,所以图片的 宽、高 肯定会有一边要小于另一边,要生成正方形就已最小的一边为基准,再来裁切定位另一边的显示范围
至于圆角的半径则是正方形宽的一半,用过 CSS 的就知道,画圆很方便 border-radius设为 50% 就可以了,都是一个道理
废话不多说,没图没真相,先上图吧:
原图:
变成正圆后:
下面上代码:
private Bitmap CrileBitmap(Bitmap bitmap) { //依据原有图片,重新创建一张新的图片,图片格式发生改变 Bitmap bitmap2 = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_4444); //将图片当作画布的北京 Canvas canvas = new Canvas(bitmap2); //创建画笔,设置抗锯齿 Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setColor(Color.BLUE); //设置画布填充色 canvas.drawARGB(0, 0, 0, 0); //计算绘制圆的半径 int mins = Math.min(bitmap.getWidth() / 2, bitmap.getHeight() / 2); //根据bitmap的高宽的中心点为圆点和圆的半径画图 canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2, mins, paint); //画笔重置 paint.reset(); //两个View 重叠的时候 取重叠部分 paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); //将bitmap在画布上 canvas.drawBitmap(bitmap, 0, 0, paint); return bitmap2; }
由于图片是长方形,所以图片的 宽、高 肯定会有一边要小于另一边,要生成正方形就已最小的一边为基准,再来裁切定位另一边的显示范围
至于圆角的半径则是正方形宽的一半,用过 CSS 的就知道,画圆很方便 border-radius设为 50% 就可以了,都是一个道理
android 的 UI 真是太繁琐了
还有一种就是自定义imageview
一、先上效果图
二、实现思路
- 在定义View 的onMeasure()方法里设置View的宽高相等,应该取宽高中的最小值。
- 在自定义View的onDraw()里面使用画笔paint结合BitmapShaper画出一个圆形区域。
- 上述两步已经可以实现一个圆形图片,但是如果图片大于View的设定的宽高,则只会绘制左上角的局域,内容显示不完全(如下图)。因此,还应该做好图片的缩放。
三、具体实现
1.新建一个java类 CircleImageView继承 ImageView,这个是完整的代码。
public class CircleImageView extends ImageView { private Paint mPaint; //画笔 private int mRadius; //圆形图片的半径 private float mScale; //图片的缩放比例 public CircleImageView(Context context) { super(context); } public CircleImageView(Context context, AttributeSet attrs) { super(context, attrs); } public CircleImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //因为是圆形图片,所以应该让宽高保持一致 int size = Math.min(getMeasuredWidth(), getMeasuredHeight()); mRadius = size / 2; setMeasuredDimension(size, size); } @Override protected void onDraw(Canvas canvas) { mPaint = new Paint(); Bitmap bitmap = drawableToBitmap(getDrawable()); //初始化BitmapShader,传入bitmap对象 BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); //计算缩放比例 mScale = (mRadius * 2.0f) / Math.min(bitmap.getHeight(), bitmap.getWidth()); Matrix matrix = new Matrix(); matrix.setScale(mScale, mScale); bitmapShader.setLocalMatrix(matrix); mPaint.setShader(bitmapShader); //画圆形,指定好中心点坐标、半径、画笔 canvas.drawCircle(mRadius, mRadius, mRadius, mPaint); } //写一个drawble转BitMap的方法 private Bitmap drawableToBitmap(Drawable drawable) { if (drawable instanceof BitmapDrawable) { BitmapDrawable bd = (BitmapDrawable) drawable; return bd.getBitmap(); } int w = drawable.getIntrinsicWidth(); int h = drawable.getIntrinsicHeight(); Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, w, h); drawable.draw(canvas); return bitmap; }}
2. onMeasure()方法里面,计算好宽高
因为是圆形图片,所以应该让宽高保持一致,取测量尺寸宽高中的最小值最为最终结果。
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //因为是圆形图片,所以应该让宽高保持一致 int size = Math.min(getMeasuredWidth(), getMeasuredHeight()); mRadius = size / 2; setMeasuredDimension(size, size); }
3. onDraw()方法里面画出圆形图片,注意看注释,很详细。
@Override protected void onDraw(Canvas canvas) { mPaint = new Paint(); Bitmap bitmap = drawableToBitmap(getDrawable()); //初始化BitmapShader,传入bitmap对象 BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); //计算缩放比例 mScale = (mRadius * 2.0f) / Math.min(bitmap.getHeight(), bitmap.getWidth()); Matrix matrix = new Matrix(); matrix.setScale(mScale, mScale); bitmapShader.setLocalMatrix(matrix); mPaint.setShader(bitmapShader); //画圆形,指定好中心点坐标、半径、画笔 canvas.drawCircle(mRadius, mRadius, mRadius, mPaint); }
4. 上一步中的将drwable转换为bitmap的方法。
//写一个drawble转BitMap的方法 private Bitmap drawableToBitmap(Drawable drawable) { if (drawable instanceof BitmapDrawable) { BitmapDrawable bd = (BitmapDrawable) drawable; return bd.getBitmap(); } int w = drawable.getIntrinsicWidth(); int h = drawable.getIntrinsicHeight(); Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, w, h); drawable.draw(canvas); return bitmap; }
四、使用该自定义View
布局文件里面使用,此处使用了斯嘉丽的美图
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.roundimage.MainActivity" > <com.roundimage.CircleImageView android:id="@+id/image1" android:layout_width="200dp" android:layout_height="200dp" android:layout_centerInParent="true" android:scaleType="centerCrop" android:src="@drawable/beauty" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/image1" android:layout_centerHorizontal="true" android:layout_marginTop="10dp" android:text="斯嘉丽·约翰逊" android:textColor="#333333" android:textSize="17sp" /></RelativeLayout>
五、总结
实现圆形图片有很多种方法:
可以使用一些开源框架如Fresco,这个可以参考他人的另一篇博客 Fresco图片框架简介及使用
笨办法,让视觉给到一张圆形图片(如果每张图都需要处理,可能她会打死你)
笨办法,用一个view在上面挡住(这个我写的自己都笑了)
自定义View,就如本文介绍的。
自定义Drawble,这个和自定义view可以相互补充。
总之,通过以上各个不同属性验证,可以发现本文的自定义View完美的实现了圆形图片。如果读者有需要圆形图的,可以把这个copy一下自己用,就一个类,简单精巧。
阅读全文
0 0
- Bitmap 搓圆
- 搓背
- 一些搓程序
- jqgrid时间搓设置
- 前天和朱狗贼出来搓
- 又是一顿搓归来
- Bitmap实现圆,保存Bitmap到文件
- bitmap圆角化
- 圆图裁剪Bitmap
- Bitmap
- bitmap
- Bitmap
- bitmap
- bitmap
- BitMap
- BITMAP
- Bitmap
- Bitmap
- live555 实时音视频(H264 & PCMA)
- cuda注意
- MindManager中主题间距/线条粗细的灵活调整
- Linux 7挂载iso文件yum源
- 第一个爬虫 Groovy + Jsoup(神器) 爬取知乎日报
- Bitmap 搓圆
- 调用jni的时候出现transformNativeLibsWithStripDebugSymbolForRelease空指针异常
- C# 实现自己画内容并打印
- MySQL + mybatis 查询业务月统计 包括 同比 环比
- 【人工智能概念】门外篇
- 关于如何减缓、解除hibernate与domain之间的强关系限制以及与mybatis简单对比
- 可视化工具–D3–比例尺的使用(quantitative)
- 商城项目实战35:购物车功能实现
- C++后台开发校招面试常见问题