android 通过修改图片像素实现CircleImageView

时间:2023-01-29 21:54:41

CircleImageView实现方法有很多种,各有优缺点,因此需要按照不同的场景使用。我们今天使用修改图片像素的方法实现CircleImageView,主要知识点无非是勾股定理和点到圆形的距离。

素材图片:

效果如下:

1、clipPath裁剪画布

该方法支持的最小版本是Android 4.3(API Level 18),方便快捷,但是不支持硬件加,此外也存在Path既有的缺点,不支持抗锯齿。

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

Paint paint = new Paint();

mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pic);
mPath = new Path();

mPath.addCircle(mBitmap.getWidth() / 2, mBitmap.getHeight() / 2, mBitmap.getWidth() / 2, Path.Direction.CCW);
canvas.clipPath(mPath);
canvas.drawBitmap(mBitmap, 0, 0, paint);
}

2、使用PorterDuffXfermode

PorterDuffXfermode是Android主流的图片合成工具,支持模式多,稳定性强,效果好,质量高,支持抗锯齿备受广大开发者喜爱,可以说是很多应用开发的首选。缺点是难度学习有些高,另外比较占内存。

/**
* 绘制圆形图片
*
*/
@Override
protected void onDraw(Canvas canvas) {

Drawable drawable = getDrawable();
if (null != drawable) {
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
Bitmap b = getCircleBitmap(bitmap);
final Rect rectSrc = new Rect(0, 0, b.getWidth(), b.getHeight());
final Rect rectDest = new Rect(0,0,getWidth(),getHeight());
paint.reset();
canvas.drawBitmap(b, rectSrc, rectDest, paint);

} else {
super.onDraw(canvas);
}
}

/**
* 获取圆形图片方法
* @param bitmap
* @param pixels
* @return Bitmap
*/
private Bitmap getCircleBitmap(Bitmap bitmap) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);

final int color = 0xff424242;

final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
paint.setAntiAlias(true);
canvas.drawColor(Color.TRANSPARENT);
paint.setColor(color);
int x = bitmap.getWidth();

canvas.drawCircle(x / 2, x / 2, x / 2, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;

}
4、设置画笔Paint的Shader,然后用该画笔绘制圆形图片

该方法是Glide和picasso使用的方法,用法简单便捷,占内占有率处于中等水平。

@Override
protected void onDraw(Canvas canvas) {

Drawable drawable = getDrawable();
if (null != drawable) {
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
Bitmap b = transform(bitmap);
final Rect rectSrc = new Rect(0, 0, b.getWidth(), b.getHeight());
final Rect rectDest = new Rect(0,0,getWidth(),getHeight());
paint.reset();
canvas.drawBitmap(b, rectSrc, rectDest, paint);

} else {
super.onDraw(canvas);
}
}

public Bitmap transform(Bitmap source) {
int size = Math.min(source.getWidth(), source.getHeight());

int x = (source.getWidth() - size) / 2;
int y = (source.getHeight() - size) / 2;

Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size);
if (squaredBitmap != source) {
source.recycle();
}

Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig());

Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
BitmapShader shader = new BitmapShader(squaredBitmap,
BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);

float mScale = (mRadius * 2.0f) / Math.min(bitmap.getHeight(), bitmap.getWidth());

Matrix matrix = new Matrix();
matrix.setScale(mScale, mScale);
bitmapShader.setLocalMatrix(matrix);

paint.setShader(shader);
paint.setAntiAlias(true);

float r www.michenggw.com= size / 2f;
canvas.drawCircle(r, r, r, paint);

squaredBitmap.recycle();
return bitmap;
}
5、修改像素

该方法支持抗锯齿,用法简单,内存占有率同样处于中等水平。

public class CircleImageView extends AppCompatImageView {

public CircleImageView(Context context) {
this(context,null);
}

public CircleImageView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}

public CircleImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}

@Override
public void onDraw(Canvas canvas) {

int width = getWidth();
int height = getHeight();

int minSize = Math.min(width,height)/2;
Drawable drawable www.dasheng178.com= getDrawable();
if(drawable!=null && minSize!=www.dfgjpt.com0) {

if(Math.min(drawable.getIntrinsicWidth(www.078881.cn/),drawable.getIntrinsicHeight())==0) {
super.onDraw(canvas);
return;
}

int intrinsicWidth = drawable.getIntrinsicWidth();
int intrinsicHeight = drawable.getIntrinsicHeight();

float R = Math.min(intrinsicWidth,intrinsicHeight)/2;

Bitmap bmp = Bitmap.createBitmap(intrinsicWidth, intrinsicHeight, Bitmap.Config.ARGB_8888);
Canvas targetCanvas = new Canvas(bmp);

drawable.draw(targetCanvas);

for (int y=0;y<intrinsicHeight;y++){
for (int x=0;www.18037.cnx<intrinsicWidth;x++){
if((Math.pow(www.17093.cn x-intrinsicWidth/2,2) + Math.pow(y-intrinsicHeight/2,2))<=Math.pow(R,2)){
continue;
}
bmp.setPixel(x,y, Color.TRANSPARENT);
}
}

Matrix imageMatrix = getImageMatrix();
if(imageMatrix!=null){
canvas.concat(imageMatrix);
}
final int saveCount = canvas.getSaveCount();
canvas.save();

if (getCropToPadding()) {
final int scrollX = getScrollX();
final int scrollY = getScrollY();
canvas.clipRect(scrollX + getPaddingLeft(), scrollY + getPaddingTop(),
scrollX + getRight() - getLeft() - getPaddingRight(),
scrollY + getBottom() - getTop() - getPaddingBottom());
}

canvas.translate(getPaddingLeft(www.60910.cn),getPaddingTop());

DrawFilter drawFilter = canvas.getDrawFilter();
canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG));
canvas.drawBitmap(bmp,0,0,null);
canvas.setDrawFilter(drawFilter);

canvas.restoreToCount(saveCount);

bmp.recycle();

}else{
super.onDraw(canvas);

android 通过修改图片像素实现CircleImageView的更多相关文章

  1. Android动态修改图片颜色的实现方式分析

    版权声明:本文为博主原创文章,未经博主允许不得转载. 1.修改色相.饱和度.亮度 参看:http://blog.csdn.NET/sjf0115/article/details/7267063 2.使 ...

  2. android 之修改图片的某一颜色值

    首先我们来创建一个叫Image的类,这个类主要用来处理与图有关的一些操作. package org.cn.tools; import java.io.IOException; import java. ...

  3. Android 实现对图片 Exif 的修改(Android 自带的方法)

    很多时候我们都要对我们的图片信息进行一些处理,比如向图片中写入经纬度,拍摄时间,设备信息,作者等等. 这个时候我们就要对我们的图片Exif进行写入信息的操作,当然,我们想知道图片的Exif信息,也可以 ...

  4. android 加载图片框架--Glide使用详解

    一.简介 Glide,一个被google所推荐的图片加载库,作者是bumptech.这个库被广泛运用在google的开源项目中,包括2014年的google I/O大会上发布的官方app.(PS:众所 ...

  5. Android开发笔记——图片缓存、手势及OOM分析

    把图片缓存.手势及OOM三个主题放在一起,是因为在Android应用开发过程中,这三个问题经常是联系在一起的.首先,预览大图需要支持手势缩放,旋转,平移等操作:其次,图片在本地需要进行缓存,避免频繁访 ...

  6. Android 圆形&sol;圆角图片的方法

    Android 圆形/圆角图片的方法 眼下网上有非常多圆角图片的实例,Github上也有一些成熟的项目.之前做项目,为了稳定高效都是选用Github上的项目直接用.但这样的结束也是Android开发必 ...

  7. Android微信九宫格图片展示控件

    版权声明:本文为xing_star原创文章,转载请注明出处! 本文同步自http://javaexception.com/archives/214 Android微信九宫格图片展示控件 半年前,公司产 ...

  8. 利用Photoshop修改图片以达到投稿要求

    摘自:http://www.dxy.cn/bbs/thread/8602152#8602152 利用Photoshop修改图片以达到投稿要求 软件版本为Photoshop CS V8.0.1(中文版) ...

  9. Android中获取图片的宽和高

    在Android中,我们想获取图片的宽和高应该怎么办?一.正常加载图片的方法下获取宽和高 举一个简单的例子:创建一个图片的副本 //加载原图 Bitmap bmSrc = BitmapFactory. ...

随机推荐

  1. 【maven】maven各种奇葩问题

    问题1:Could not calculate build plan: Plugin org.apache... 不能成功创建maven项目 解决方法1: http://repo1.maven.org ...

  2. 正则表达式获取字符串中的img标签中的url链接

    废话不多说直接看代码 JavaScript中的代码: var re = /src=\"([^\"]*?)\"/i; var arr = str.match(re); if ...

  3. python3 入门 &lpar;四&rpar; 类与继承

    Python 类 Python中的类提供了面向对象编程的所有基本功能:类的继承机制允许多个基类,派生类可以覆盖基类中的任何方法,方法中可以调用基类中的同名方法. 对象可以包含任意数量和类型的数据. p ...

  4. extern C的作用详解

    extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码.加上extern "C"后,会指示编译器这部分代码按C语言的进行编译,而不是C+ ...

  5. &period;NET并行与多线程学习系列一

    并行与多线程学习系列一 一.并行初试: public static void test() { ; i < ; i++) { Console.WriteLine(i); } } public s ...

  6. win10 uwp 打开文件管理器选择文件

    本文:让文件管理器选择文件,不是从文件管理器获得文件. 假如已经获得一些文件,那么如何从文件管理器选择这些文件? 使用方法很简单. 从网上拿图来说 打开文件夹自动选择所有文件 首先需要获得文件夹,因为 ...

  7. VMware-vCenter-Server-Appliance VCSA升级步骤

    1.下载ZIP升级文件并解压 2.打开HFS,把解压后的文件夹拖到"Virtual File System"下,在弹出的对话框中点击"Virtual folder&quo ...

  8. Storm入门(十一)Twitter Storm源代码分析之CoordinatedBolt

    作者: xumingming | 可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://xumingming.sinaapp.com/811/twitter-stor ...

  9. Error&colon; Program type already present&colon; android&period;arch&period;lifecycle&period;LifecycleRegistry&dollar;1

    com.firebaseui:firebase-ui-firestore:3.1.0 depends on android.arch.lifecycle:extensions:1.0.0-beta1. ...

  10. SPOJ - DWARFLOG Manipulate Dwarfs 线段树&plus;想法题;

    题意:给你2e5个矮人,编号1~N.有2e5个操作:操作1 读取x,y,交换编号为x,y的矮人.操作2 读取AB 判断编号为A,A+1····B的矮人是否连续(不必有序). 题解:首先用pos[i]保 ...