-
Android绘制圆形ImageView的几种实现方法
2016-08-22 15:31:20圆形Imagview有几种方法,这里我列举两种方法出来仅供大家参考,当然还有其它的几种方法,我就不一一赘述了 1.重写onDraw(Canvas canvas)通过Canvas来画圆,传入带bitmapShaper的画笔 public class ...圆形Imagview有几种方法,这里我列举两种方法出来仅供大家参考,当然还有其它的几种方法,我就不一一赘述了
1.重写onDraw(Canvas canvas)通过Canvas来画圆,传入带bitmapShaper的画笔
public class CircleImageView extends ImageView { public CircleImageView(Context context) { super(context); init(); } public CircleImageView(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init(){ //创建画笔 paint = new Paint(); paint.setAntiAlias(true); // 防止边缘的锯齿 paint.setColor(Color.WHITE); // 这里的颜色决定了边缘的颜色 mShaderMatrix=new Matrix(); } /** * 位图对象 * */ private Bitmap mbitmap; Paint paint; protected void onDraw(Canvas canvas) { Drawable drawable = getDrawable(); if (drawable == null) { return; } if (getWidth() == 0 || getHeight() == 0) { return; } if(mbitmap==null){ mbitmap=DrawableToBitmap(drawable); setBitmapsharder(); } if(mbitmap==null) return; int radius=getWidth()> getHeight()?getHeight()/2:getWidth()/2; canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius, paint); } BitmapShader mBitmapShader=null; private void setBitmapsharder(){ if (mbitmap!=null&&paint!=null&&width!=0&&height!=0){ mBitmapShader=new BitmapShader(mbitmap, Shader.TileMode.CLAMP,Shader.TileMode.CLAMP); paint.setShader(mBitmapShader); float scale=0; mBitmapHeight = mbitmap.getHeight(); mBitmapWidth = mbitmap.getWidth(); mShaderMatrix.set(null); if (width>height) { if(mBitmapWidth>mBitmapHeight) scale=((float)height)/mBitmapHeight; else scale=((float)height)/mBitmapWidth; } else { if(mBitmapWidth>mBitmapHeight) scale=((float)width)/mBitmapHeight; else scale=((float)width)/mBitmapWidth; } //设置图片缩放 mShaderMatrix.setScale(scale, scale); //设置图片平移显示 if(mBitmapWidth>mBitmapHeight){ mShaderMatrix.postTranslate(-(mBitmapWidth-mBitmapHeight)*scale/2,0); }else{ mShaderMatrix.postTranslate(0,-(mBitmapHeight-mBitmapWidth)*scale/2); } mBitmapShader.setLocalMatrix(mShaderMatrix); } } Matrix mShaderMatrix; private int mBitmapWidth; private int mBitmapHeight; private int height; private int width; @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); height=getHeight(); width=getWidth(); setBitmapsharder(); } @Override public void setImageBitmap(Bitmap bm) { super.setImageBitmap(bm); mbitmap=bm; setBitmapsharder(); } @Override public void setImageDrawable(Drawable drawable) { super.setImageDrawable(drawable); mbitmap=DrawableToBitmap(drawable); setBitmapsharder(); } @Override public void setImageResource(int resId) { super.setImageResource(resId); mbitmap=DrawableToBitmap(getContext(),resId); setBitmapsharder(); } @Override public void setImageURI(Uri uri) { super.setImageURI(uri); mbitmap=DrawableToBitmap(getDrawable()); setBitmapsharder(); } /** * Drawable转换为Bitmap * */ public static Bitmap DrawableToBitmap(Drawable drawable){ if(drawable==null) return null; if(drawable instanceof BitmapDrawable) return ((BitmapDrawable)drawable).getBitmap(); Bitmap bitmap=null; //如果是ColorDrawable随便给一个宽高 if(drawable instanceof ColorDrawable) bitmap=Bitmap.createBitmap(2,2,Bitmap.Config.ARGB_8888); else bitmap=Bitmap.createBitmap(drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight(),Bitmap.Config.ARGB_8888); Canvas canvas=new Canvas(bitmap); //设置绘制的矩形区域 drawable.setBounds(0,0,drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight()); drawable.draw(canvas); return bitmap; } /** * Drawable转换为Bitmap * */ public static Bitmap DrawableToBitmap(Context mContext,int ResId){ Bitmap bitmap= BitmapFactory.decodeResource(mContext.getResources(),ResId); return bitmap; } }
这里的有几个核心的点有第一个就是ondraw里面画圆,注意圆心的坐标以及圆的半径(半径为最小)
第二点通过setBitmapSharder方法,里面t通过Martix设置位图的缩放比例以及位图的偏移量
关于Martix的操作
Matrix的操作,总共分为translate(平移),rotate(旋转),scale(缩放)和skew(倾斜)四种,每一种变换在 Android的API里都提供了set, post和pre三种操作方式,除了translate,其他三种操作都可以指定中心点。
set是直接设置Matrix的值,每次set一次,整个Matrix的数组都会变掉。
post是后乘,当前的矩阵乘以参数给出的矩阵。可以连续多次使用post,来完成所需的整个变换。
具体怎么用的可以去参考一下片文章Android Matrix详解
2.通过绘制圆形的Bitmap,绘制Imagvivew
public class CircleImageView extends ImageView { public CircleImageView(Context context) { super(context); init(); } public CircleImageView(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init(){ mScaleType=getScaleType(); //创建画笔 paint = new Paint(); paint.setAntiAlias(true); // 防止边缘的锯齿 paint.setColor(Color.BLACK); // 这里的颜色决定了边缘的颜色 } /** * 位图对象 * */ private Bitmap mbitmap; Paint paint; private Rect rect=new Rect(); ScaleType mScaleType; protected void onDraw(Canvas canvas) { Drawable drawable = getDrawable(); if (drawable == null) { return; } if (getWidth() == 0 || getHeight() == 0) { return; } if(mbitmap==null){ mbitmap=DrawableToBitmap(drawable); } if(mbitmap==null) return; int radius=getWidth()> getHeight()?getHeight()/2:getWidth()/2; canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius, paint); //把圆形bitmap居中对齐 canvas.drawBitmap(drawCircleBitmap(mbitmap, radius), getWidth() / 2-radius,getHeight() / 2-radius, paint); } /* *画圆形的bitmap * */ public static Bitmap drawCircleBitmap(Bitmap bmp, int radius){ if (bmp.getWidth() != radius || bmp.getHeight() != radius){ /** * 把图片进行缩放,以宽高最小的一方为准,缩放图片比例 * */ double diameter=radius*2;//获取直径 if(bmp.getWidth()> bmp.getHeight()){ bmp = Bitmap.createScaledBitmap(bmp, (int)( diameter*bmp.getWidth()/bmp.getHeight()), (int)diameter, false); }else if(bmp.getWidth()< bmp.getHeight()){ bmp = Bitmap.createScaledBitmap(bmp, (int)(diameter/bmp.getWidth()*bmp.getHeight()), (int) diameter, false); }else{ bmp = Bitmap.createScaledBitmap(bmp, (int)diameter, (int)diameter, false); } } Bitmap output = Bitmap.createBitmap(radius*2, radius*2, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(output); //设置画笔全透明 canvas.drawARGB(0, 0, 0, 0); Paint paints = new Paint(); paints.setColor(Color.WHITE); paints.setAntiAlias(true);//去锯齿 paints.setFilterBitmap(true); //防抖动 paints.setDither(true); //把图片圆形绘制在面部中心 canvas.drawCircle(radius, radius, radius, paints); // 取两层绘制交集。显示前景色。 paints.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); Rect rect=new Rect(); if(bmp.getWidth()>=bmp.getHeight()){ rect.set(bmp.getWidth()/2-radius,0,bmp.getWidth()/2+radius,radius*2); }else{ rect.set(0,bmp.getHeight()/2-radius,radius*2,bmp.getHeight()/2+radius); } Rect rect2=new Rect(0,0,radius*2,radius*2); //第一个rect 针对bmp的绘制区域,rect2表示绘制到上面位置 canvas.drawBitmap(bmp, rect, rect2, paints); bmp.recycle(); return output; } /** * 设置显示类型 * */ @Override public void setScaleType(ScaleType scaleType) { super.setScaleType(scaleType); mScaleType=scaleType; } @Override public void setImageBitmap(Bitmap bm) { super.setImageBitmap(bm); mbitmap=bm; } @Override public void setImageDrawable(Drawable drawable) { super.setImageDrawable(drawable); mbitmap=DrawableToBitmap(drawable); } @Override public void setImageResource(int resId) { super.setImageResource(resId); mbitmap=DrawableToBitmap(getContext(),resId); } @Override public void setImageURI(Uri uri) { super.setImageURI(uri); mbitmap=DrawableToBitmap(getDrawable()); } /** * Drawable转换为Bitmap * */ public static Bitmap DrawableToBitmap(Drawable drawable){ if(drawable==null) return null; if(drawable instanceof BitmapDrawable) return ((BitmapDrawable)drawable).getBitmap(); Bitmap bitmap=null; //如果是ColorDrawable随便给一个宽高 if(drawable instanceof ColorDrawable) bitmap=Bitmap.createBitmap(2,2,Bitmap.Config.ARGB_8888); else bitmap=Bitmap.createBitmap(drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight(),Bitmap.Config.ARGB_8888); Canvas canvas=new Canvas(bitmap); //设置绘制的矩形区域 drawable.setBounds(0,0,drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight()); drawable.draw(canvas); return bitmap; } /** * Drawable转换为Bitmap * */ public static Bitmap DrawableToBitmap(Context mContext,int ResId){ Bitmap bitmap= BitmapFactory.decodeResource(mContext.getResources(),ResId); return bitmap; } }
这个中绘制方法更简单我觉得可以不用重新Imagview就可以实现,把drawCircleBitmap方法就行封装一下得到圆形的bitmap然后在设置给Imageveiw就可以实现了绘制好之后记得把之前的的bitmap给reclye了这里画圆形view使用是在画布上面画一个圆,然后把bitmap也画上去,然后去交叉前景图
具体paint.setXfermode(newPorterDuffXfermode(PorterDuff.Mode.SRC_IN))
这里面的几种交叉取景可以参考Android Paint之 setXfermode PorterDuffXfermode 讲解这篇文字
3.还要其他的几种方式,比如画一个中间透明的圆形遮盖在上面等等
-
计算机图形学的算法基础(原书第2版)--详细书签版
2012-10-17 03:40:532.4 圆的生成—Bresenham算法 57 2.5 椭圆的生成 64 2.6 一般函数的光栅化 69 2.7 扫描转换—显示的生成 71 2.7.1 实时扫描转换 71 2.7.2 使用指针的简单活化边表 72 2.7.3 排序活化边表 72 2.7.4 使用链表... -
2D绘图基础
2017-12-25 16:53:00它提供了各种绘制图形的API,如drawPoint(点)、drawLine(线)、drawRect(矩形)、drawVertices(多边形)、drawArc(弧)、drawCircle(圆),等等。通过它们的名字,基本上可以大致了解他们的功能。当然,Paint作为一个非常...系统通过提供Canvas对象来提供绘图方法。它提供了各种绘制图形的API,如drawPoint(点)、drawLine(线)、drawRect(矩形)、drawVertices(多边形)、drawArc(弧)、drawCircle(圆),等等。通过它们的名字,基本上可以大致了解他们的功能。当然,Paint作为一个非常重要的元素,功能也是很强大的,这里简单地列举了一些它的属性和对象的功能。
- setAntiAlias(); //设置画笔的锯齿效果
- setColor(); //设置画笔的颜色
- setARGB(); //设置画笔的A、R、G、B值
- setAlpha(); //设置画笔的Aplha值
- setTextSize(); //设置字体尺寸
- setStyle(); //设置画笔的风格
- setStrokeWidth();//设置空心边框的宽度
正式由于画笔的功能的不一样,再结合各种不同的绘图API。这样任意组合就可以实现不同的绘图效果,如果同样是矩形,设置Paint的Style,就可以画出是空心还是实心的矩形。
如下图,就是使用如下代码绘制出来的效果。
paint.setStyle(Paint.Style.STROKE);
同样的参数如果使用如下代码来设置Paint的属性。那么绘制出来的效果如下图所示。
paint.setStyle(Paint.Style.FILL);
上面我们初步了解了绘制不同图形的基本方法,下面来重点看看Canvas家族的各个成员们。
- DrawPoint,绘制点。
canvas.drawPoint(x,y,paint);
DrawLine,绘制直线
canvas.drawLine(startX,startY,endX,endY,paint);
- DrawLines,绘制多条直线
float[] pts = { startX1,startY1,endX1,endY1, ... startXN,startYN,endXN,endYN }; canvas.drawLine(pts,paint);
- DrawRect,绘制矩形,效果如图6.6所示。
canvas.drawRect(left,top,right,bottom,paint,paint);
- DrawRoundRect,绘制圆角矩形
canvas.drawRoundRect(left,top,right,bottom,radiusX,radiusY,paint);
- DrawCircle,绘制圆
canvas.drawCircle(circleX,circleY,radois,paint);
- DrawArc,绘制弧线、扇形,其中startAngle为开始的弧度,sweepAngle为圆弧的角度,注释如下所示。
paint.setStyle(Paint.Style.STROKE); canvas.drawArc(left,top,right,bottom,startAngle,sweepAngle,useCenter,paint);
这里需要注意下,绘制弧形与扇形的区分就是倒数第二个参数useCenter的区别,如下图所示,即为使用不同的Paint.Style和useCenter属性产生的不同效果
Paint.Style.STROKE 和 useCenter为true Paint.Style.STROKE 和 useCenter为false
Paint.Style.FILL 和 useCenter为true Paint.Style.FILL 和 useCenter为false
- DrawOval,绘制椭圆
//通过椭圆的外接矩形来绘制椭圆 canvas.drawOval(left,top,right,bottom,paint);
- DrawText,绘制文本。
canvas.drawText(text,startX,startY,paint);
- DrawPosText,在指定位置绘制文本。
canvas.drawPosText(text, new float[]{X1,Y1, X2,Y2 ...... Xn,Yn}, paint);
- DrawPath,绘制路径
Path path = new Path(); path.moveTo(50,50); path.lineTo(100,100); path.lineTo(100,300); path.lineTo(300,500); canvas.drawPath(path,paint);
-
Java开发实战1200例(第2卷)(完整版).(清华出版.李钟尉.陈丹丹).part1
2016-06-12 23:30:05实例006 绘制指定角度的填充扇形 8 实例007 绘制多边形 9 实例008 绘制二次曲线 10 实例009 绘制三次曲线 12 实例010 绘制文本 13 实例011 设置文本的字体 14 实例012 设置文本和图形的颜色 15 1.2 笔画和图形处理 ... -
Visual C++开发实战1200例(第1卷).(清华出版.刘锐宁.梁水.李伟明).part1
2016-06-16 01:35:39实例212 重写父类中的方法 实例213 计算几何图形的面积 实例214 简单的汽车销售商场 实例215 利用拷贝构造函数简化实例创建 实例216 访问类中私有成员的函数 实例217 实现类的加法运算 实例218 在类中实现... -
Visual C++开发实战1200例(第1卷).(清华出版.刘锐宁.梁水.李伟明).part2
2016-06-16 01:38:19实例212 重写父类中的方法 实例213 计算几何图形的面积 实例214 简单的汽车销售商场 实例215 利用拷贝构造函数简化实例创建 实例216 访问类中私有成员的函数 实例217 实现类的加法运算 实例218 在类中实现... -
AutoCAD VBA二次开发教程.PDF
2015-07-01 12:31:25分析了直线、圆、圆弧和样条曲线向多段线的转化,提供了一些常用的多段线操作,提出制图法解决问题的新思路,编写了根据起点、终点和弧长创建圆弧的函数,最后又给出绘制放样展开图的方法。 第4章包含了两个有用的... -
Microsoft C# Windows程序设计(上下册)
2011-08-05 10:28:1313.4 使用贝塞尔曲线绘制圆和弧 13.5 贝塞尔艺术作品 13.6 数学推导 13.7 标准样条曲线 13.8 标准样条曲线的公式推导 第十四章 菜单 14.1 菜单和菜单项 14.2 菜单快捷键 14.3 第一个菜单 14.4 非... -
22 操作图像中像素的方法二:用迭代器操作像素 5.1.5、5.1.6 23 操作图像中像素的方法三:动态地址计算 5.1.5、5.1.6 24 遍历图像中像素的14种方法 5.1.6 25 初级图像混合 5.2.4 26 多通道图像混合 5.3.3 27 ...
-
Delphi7应用编程150例
2018-04-05 15:23:33使用本书最好的方法是通过学习掌握实例中的技术或技巧,然后使用这些技术尝试实现更复杂的功能并应用到更多方面。 本书内容丰富、结构合理,可以作为广大编程爱好者提高编程水平的自学教材,也可以供程序开发人员和... -
EXCEL 2007 宝典 附光盘文件
2010-04-02 14:43:05depreciation.xlsx:一个演示计算资产折旧的方法的工作簿。 investment calculations.xlsx:一个演示计算投资利润的公式的工作簿。 irregular payments.xlsx:一个演示不规则还款的贷款计算的工作簿。 loan ... -
Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3
2016-06-12 11:39:31实例144 Object类中线程相关的方法 187 实例145 哲学家就餐问题 189 实例146 使用信号量实现线程同步 190 实例147 使用原子变量实现线程同步 191 实例148 使用事件分配线程更新Swing控件 193 实例149 使用... -
Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part1
2016-06-12 11:34:39实例144 Object类中线程相关的方法 187 实例145 哲学家就餐问题 189 实例146 使用信号量实现线程同步 190 实例147 使用原子变量实现线程同步 191 实例148 使用事件分配线程更新Swing控件 193 实例149 使用... -
Java Web开发实战1200例(第2卷)(完整版).(清华出版.卢瀚.王春斌).part1
2016-06-13 20:03:04实例068 列举SQL Server数据库中的数据表 实例069 列举MySQL数据库中的数据表 实例070 查看数据表结构 实例071 动态维护投票数据库 实例072 SQL Server数据库的备份 实例073 SQL Server数据库的恢复 实例074 MySQL... -
《Java开发实战1200例(第I卷)》(李钟尉.陈丹丹).part2 高清完整PDF版
2016-06-13 15:53:27实例144 Object类中线程相关的方法 实例145 哲学家就餐问题 实例146 使用信号量实现线程同步 实例147 使用原子变量实现线程同步 实例148 使用事件分配线程更新Swing控件 实例149 使用SwingWorker类完成耗时... -
《Java开发实战1200例(第I卷)》(李钟尉.陈丹丹).part3 高清完整PDF版
2016-06-13 16:11:24实例144 Object类中线程相关的方法 实例145 哲学家就餐问题 实例146 使用信号量实现线程同步 实例147 使用原子变量实现线程同步 实例148 使用事件分配线程更新Swing控件 实例149 使用SwingWorker类完成耗时... -
软件工程师典藏:C#程序开发范例宝典(第2版).part01
2012-11-11 20:05:51实例121 波形图的绘制 179 4.2 图形转换 180 实例122 BMP转换成JPG格式 181 实例123 JPG转换成BMP格式 182 实例124 位图转化为WMF格式 183 实例125 ICO文件转化为位图 184 实例126 图片批量转换工具 185 4.3 图像... -
C#程序开发范例宝典(第2版).part02
2012-11-12 07:55:11实例121 波形图的绘制 179 4.2 图形转换 180 实例122 BMP转换成JPG格式 181 实例123 JPG转换成BMP格式 182 实例124 位图转化为WMF格式 183 实例125 ICO文件转化为位图 184 实例126 图片批量转换工具 185 4.3 ... -
C#程序开发范例宝典(第2版).part13
2012-11-12 20:17:14实例121 波形图的绘制 179 4.2 图形转换 180 实例122 BMP转换成JPG格式 181 实例123 JPG转换成BMP格式 182 实例124 位图转化为WMF格式 183 实例125 ICO文件转化为位图 184 实例126 图片批量转换工具 185 4.3 ... -
C#程序开发范例宝典(第2版).part08
2012-11-12 08:04:21实例121 波形图的绘制 179 4.2 图形转换 180 实例122 BMP转换成JPG格式 181 实例123 JPG转换成BMP格式 182 实例124 位图转化为WMF格式 183 实例125 ICO文件转化为位图 184 实例126 图片批量转换工具 185 4.3 ... -
C#程序开发范例宝典(第2版).part03
2012-11-12 07:56:38实例121 波形图的绘制 179 4.2 图形转换 180 实例122 BMP转换成JPG格式 181 实例123 JPG转换成BMP格式 182 实例124 位图转化为WMF格式 183 实例125 ICO文件转化为位图 184 实例126 图片批量转换工具 185 4.3 ... -
程序开发范例宝典>>
2012-10-24 10:41:28实例121 波形图的绘制 179 4.2 图形转换 180 实例122 BMP转换成JPG格式 181 实例123 JPG转换成BMP格式 182 实例124 位图转化为WMF格式 183 实例125 ICO文件转化为位图 184 实例126 图片批量转换... -
书 名:程序开发范例宝典>>【中卷】(分三卷上传完本书案例)
2010-04-05 21:59:37实例121 波形图的绘制 179 4.2 图形转换 180 实例122 BMP转换成JPG格式 181 实例123 JPG转换成BMP格式 182 实例124 位图转化为WMF格式 183 实例125 ICO文件转化为位图 184 实例126 图片批量转换工具 ... -
书 名:程序开发范例宝典>>【下卷】(分三卷上传完本书案例)
2010-04-05 03:24:09实例121 波形图的绘制 179 4.2 图形转换 180 实例122 BMP转换成JPG格式 181 实例123 JPG转换成BMP格式 182 实例124 位图转化为WMF格式 183 实例125 ICO文件转化为位图 184 实例126 图片批量转换工具 ... -
Java开发实战1200例.第2卷.part3
2013-05-08 22:46:34实例068 列举SQL Server数据库中的数据表 133 实例069 列举MySQL数据库中的数据表 134 实例070 查看数据表结构 135 实例071 动态维护投票数据库 136 实例072 SQL Server数据库的备份 139 实例073 SQL Server数据库的... -
Java开发实战1200例.第2卷.part2
2013-05-08 22:45:35实例068 列举SQL Server数据库中的数据表 133 实例069 列举MySQL数据库中的数据表 134 实例070 查看数据表结构 135 实例071 动态维护投票数据库 136 实例072 SQL Server数据库的备份 139 实例073 SQL Server数据库的... -
Java开发实战1200例.第2卷.part1
2013-05-08 22:44:13实例068 列举SQL Server数据库中的数据表 133 实例069 列举MySQL数据库中的数据表 134 实例070 查看数据表结构 135 实例071 动态维护投票数据库 136 实例072 SQL Server数据库的备份 139 实例073 SQL Server数据库的... -
看到网上有个方案说:主项目负责加载组件,由于主项目和组件之间是隔离的,那么主项目如何调用组件ApplicationLike的生命周期方法呢,目前采用的是基于编译期字节码插入的方式,扫描所有的ApplicationLike类(其有一...
-
C#.net_经典编程例子400个
2013-05-17 09:25:30165 实例113 波形图的绘制 166 4.2 图形转换 168 实例114 BMP转换成JPG格式 168 实例115 JPG转换成BMP格式 170 实例116 位图转化为WMF 171 实例117 Ico文件转化为位图 172 实例118... -
C#编程经验技巧宝典
2008-06-01 08:59:33C#编程经验技巧宝典源代码,目录如下: 第1章 开发环境 1 <br>1.1 Visual Studio开发环境安装与配置 2 <br>0001 安装Visual Studio 2005开发环境须知 2 <br>0002 配置合适的Visual Studio 2005...