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

【KDD2024】ShapeFormer:用于多元时间序列分类的Shapelet Transformer 多元时间序列分类(MTSC)因其在现实世界中的广泛应用而吸引了大量研究关注。最近,Transformer在MTSC中取得了先进的性能。然而, 阅读详情

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;  
        
        
    }  

3、设置画笔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 = size / 2f;
            canvas.drawCircle(r, r, r, paint);

            squaredBitmap.recycle();
            return bitmap;
        }

4.修改像素

该方法无法支持抗锯齿,并且不支持Bitmap.Config.HARDWARE格式的bitmap,但用法简单,内存占有率同样处于比较低。

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 = getDrawable();
        if(drawable!=null && minSize!=0) {

            if(Math.min(drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight())==0) {
                return;
            }

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

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

            Bitmap bmp = transformBitmap(drawable, intrinsicWidth, intrinsicHeight, R);

            Matrix imageMatrix = getImageMatrix();

            if((imageMatrix==null || imageMatrix.isIdentity()) && getPaddingTop()==0 && getPaddingLeft()==0){
                drawCircleImage(canvas, bmp);

            }else {
                if (imageMatrix != null && !imageMatrix.isIdentity()) {
                    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(), getPaddingTop());
                drawCircleImage(canvas, bmp);
                canvas.restoreToCount(saveCount);

            }
            if(bmp!=null && !bmp.isRecycled()) {
                bmp.recycle();
            }
        }else{
            super.onDraw(canvas);
        }
    }

    private void drawCircleImage(Canvas canvas, Bitmap bmp) {
        try {
            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);
        }catch (Exception e){
            e.printStackTrace();
            return;
        }
    }

    @NonNull
    private Bitmap transformBitmap(Drawable drawable, int intrinsicWidth, int intrinsicHeight, float r) {
        Bitmap bmp = Bitmap.createBitmap(intrinsicWidth, intrinsicHeight, Bitmap.Config.ARGB_8888);
        Canvas targetCanvas = new Canvas(bmp);
        try {
            drawable.draw(targetCanvas);
            for (int y = 0; y < intrinsicHeight; y++) {
                for (int x = 0; x < intrinsicWidth; x++) {
                    if ((Math.pow(x - intrinsicWidth / 2, 2) + Math.pow(y - intrinsicHeight / 2, 2)) <= Math.pow(r, 2)) {
                        continue;
                    }
                    bmp.setPixel(x, y, Color.TRANSPARENT);
                }
            }
        }catch (Exception e){
            NCFLog.e("transformBitmap","e="+e.getLocalizedMessage());
            e.printStackTrace();
        }
        return bmp;
    }

    public boolean isHardware(Bitmap sourceBitmap){
        if(sourceBitmap==null) return  false;
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O) {
            return sourceBitmap.getConfig() == Bitmap.Config.HARDWARE;
        }
        return false;
    }

}

更多学习内容,视频教学请关注我的主页查询获取
在这里插入图片描述

Linux Namespace隔离实战:dd/mkfs/mount/unshare构建终极沙箱 内存占用 | 512MB+ | **<10MB** | 50倍节省 || 启动时间 | 15-45秒 | **0.1-0.5秒** | 100倍加速 || 磁盘空间 | GB级 | **MB级** | 显著减少 || 系统调用性能 | 有损耗 | **原生速度** | 零损耗 | 阅读详情

相关推荐

GPS定位不准?可能是GDOP在作怪!手把手教你优化卫星几何分布

本文深入解析了GPS定位精度不佳的常见原因——几何精度因子GDOP。通过剖析卫星几何分布对定位误差的放大效应,文章提供了从理解GDOP、PDOP、HDOP等关键指标,到使用专业APP实时诊断卫星天空图,再到利用在线工具提前规划最佳定位时机的完整实战指南。旨在帮助户外爱好者、无人机飞手及专业用户主动优化卫星几何条件,从而显著提升定位可靠性。

weixin_29062823的博客 304

【Android -- 开源库】CircleImageView 的基本使用

快速圆形的 ImageView,非常适合个人资料图像。 这基于 Vince Mi 的 RoundedImageView,它本身基于 Romain Guy 推荐的技术。

Kevin Learn Android 3734

国产PHY芯片YT8512H替代LAN8742A的实战指南(STM32F407平台)

本文详细介绍了在STM32F407平台上,使用国产PHY芯片YT8512H替代LAN8742A的完整实战过程。文章深入剖析了硬件设计中的关键信号连接差异(如CRS_DV与RXDV复用)、时钟布线要点,并提供了软件驱动修改、PHY配置及调试排错的系统指南,旨在帮助工程师高效完成国产化替代,规避常见陷阱。

defi6farmer的博客 854

CircleImageView的使用

简介: 实现对一个图片进行圆形切割,并作为头像使用,因为在使用的过程中涉及备份到云端,那么就会出现重新加载的图片出现毛边,为了解决毛边的问题,在头像的周围添加一个圆框即可,在github上有一个开源控件叫做CircleImageView可以很好的实现圆形边框 使用: 在build.gradle的dependencies中加入 dependencies { .... impl...

DLUT_WJX的博客 1740

高效爬取懂车帝车型数据:从静态解析到动态反爬实战

本文详细解析了如何高效爬取懂车帝车型数据,从静态HTML解析到动态接口反爬的完整实战路径。文章重点介绍了使用浏览器开发者工具定位数据、应对CSS混淆与参数加密等反爬策略,并提供了整合静态与动态抓取逻辑的Python代码示例,帮助开发者稳健地获取结构化车型信息。

wind6的博客 935

数字IC后端PPA优化实战:Timing一致性策略与Module Region布局技巧

本文深入探讨了数字IC后端设计中的PPA优化实战,重点解析了Timing一致性问题及其解决方案。通过调整Clock Uncertainty、Timing Derate和RC Scale Factor等关键参数,使Innovus等PR工具的分析结果更接近PrimeTime签核结果。同时,文章详细介绍了Module Region布局技巧,通过为关键模块划定物理区域,优化单元摆放,有效减少线延迟,从而协同提升时序收敛效率与设计可预测性。

weixin_29218963的博客 202

圆头像处理~开发中经常遇到

原文出处:http://blog.youkuaiyun.com/zhoubin1992/article/details/47258639  本文分为三大部分: CircleImageView的使用CircleImageView源码分析Android自定义View总结 CircleImageView项目源码下载:  https://github.com/hdodenhof/CircleI

安逸猿 941

倍福--实现TCP/IP的配置

控制器为CX5120,需要和上位机做通信,选择TCP/IP的通讯方式,本文介绍TCP/IP通信的操作步骤。 目 录 软硬件版本 3 1.1. 倍福Beckhoff 3 1.1.1. 控制器硬件 3 1.1.2. 控制软件 3 1.2. 串口调试助手 3 1.2.1. TCP调试通信助手 3 授权文件 3 2.1 Lib文件 3 2.2. CAB文件 4 PLC程序编写 4 3.1. 引入TCP/IP库文件 4 3.2. Client端程序 5 3.2.1. 建立相关变量 5 3.3.2. 编写连接功能块

weixin_41883890的博客 5730

CircleImageView用法及源码解析(雷惊风)

首先这篇文章我们从以下四个方面进行一一讲解1.CircleImageView在AS中集成及用法;2.CircleImageView中定义的对外的方法;3.源码解析;4.用到的知识点的总计。希望通过本篇文章的学习,您会对自定义控件及自定义控件中用到的一些类有一定的了解,最后我会把我添加好详细注释的Demo下载地址附上,你也可以一边看我的Demo,一边看这篇文章,效果应该会更好,那么,我们这就开始吧!

刘永雷的专栏 1万+

YOLO11检测中的内存占用分析与优化:讲解如何分析并优化推理时的内存使用

YOLOv11模型内存分析与优化摘要:本文系统分析了YOLOv11目标检测模型的内存使用模式,重点探讨了显存(VRAM)、系统内存(RAM)和共享内存的特性差异。通过PyTorch内置工具和自定义分析器,详细剖析了骨干网络、颈部网络和检测头各组件内存占用规律,指出激活值内存与输入尺寸呈平方级增长关系。文章提供了卷积层内存计算公式,并强调合理规划"工作台"(显存)与"仓库"(内存)间的数据流动是优化关键。最后通过流程图直观展示了YOLOv11推理过程的三类内存使用模式,

本博客聚焦 YOLOv11 全流程落地,涵盖架构优化、数据集处理、训练技巧与多场景部署,兼及国产数据库、Java 开发与 AI 模型应用,内容兼顾理论与工程实践,为开发者提供系统干货,助力高效提升技术能力。 343

zynq的vitis工程烧录到Winbond(华邦)型号W25Q256JVEQ的QSPI FLAHS

vitis2023.1直接支持W25Q256JVEQ。

FPGA艺术家的博客 674

推荐使用 CircleImageView - 简单易用的圆形图像视图库

推荐使用 CircleImageView - 简单易用的圆形图像视图库 1、项目介绍 在移动应用开发中,为用户提供美观、独特的UI设计是提升用户体验的关键之一。CircleImageView 是一款轻量级的Android库,它将普通的ImageView转化为圆角或圆形图片视图,无需复杂的图像处理和设置特定的 scaletype。只需简单的集成,即可让你的应用瞬间拥有优雅的个人头像展示效果。 2、项...

gitblog_00064的博客 599

PCB Layout工程师核心能力与实战进阶指南

PCB Layout是电子硬件从原理图到物理实现的关键环节,本质是将电路逻辑转化为受电磁场、热力学与制造工艺约束的三维空间结构。其设计质量直接决定信号完整性(SI)、电源完整性(PI)和电磁兼容性(EMC)等核心性能指标。随着高速接口(如PCIe Gen5、USB3.2)、高密度封装(BGA微间距、HDI)及车规/工业级可靠性要求提升,Layout已从‘连线’演进为多目标协同优化的系统工程。掌握Altium Designer等EDA工具、理解叠层设计与DFM规则、具备SI/PI仿真意识,并能贯通芯片Data

weixin_42589700的博客 86

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

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33991418的博客 228

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

android图片分辨率改变,android 通过修改图片像素实现CircleImageView

CircleImageView实现方法有很多种,各有优缺点,因此需要按照不同的场景使用。我们今天使用修改图片像素的方法实现CircleImageView,主要知识点无非是勾股定理和点到圆形的距离。素材图片: 效果如下: 1、clipPath裁剪画布该方法支持的最小版本是Android 4.3(API Level 18),方便快捷,但是不支持硬件加,此外也存在Path既有的缺点,不支持抗锯齿。@...

weixin_36023533的博客 978

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Android-第三节圆形图案及shape属性(修改圆形图片)

Override//由于是圆形,宽高应保持一致@Overrideif (null!//初始化BitmapShader,传入bitmap对象//计算缩放比例//画圆形,指定好坐标,半径,画笔} else {1.创建java代码2.创建ImageView组件3.修改ImageView,将刚刚写好的代码引用二、按钮圆角2.1主要属性。

2401_84011114的博客 997

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Android-第三节圆形图案及shape属性(修改圆形图片),金三银四Android高级工程师面试题整理

在这里我和身边一些朋友特意整理了一份快速进阶为Android高级工程师的系统且全面的学习资料。涵盖了Android初级——Android高级架构师进阶必备的一些学习技能。附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。

2301_77110865的博客 981

Android 两种制作圆形/圆角图片的方法

@roykfw 前言: 目前网上有很多圆角图片的实例,Github上也有一些成熟的项目。之前做项目,为了稳定高效都是选用Github上的项目直接用。但这种结束也是Android开发必备技能 ,所以今天就来简单研究一下该技术,分享给大家。 预备知识: Xfermode介绍: 下面是Android ApiDemo里的“Xfermodes”实例,效果图。

xufeifandj的专栏 1099

CircleImageView 安装和配置指南

### 项目基础介绍 CircleImageView 是一个用于 Android 平台的开源库,旨在提供一个快速且高效的圆形 ImageView。它基于 RoundedImageView 开发,通过使用 BitmapShader 技术,避免了创建原始位图的副本,从而提高了性能。CircleImageView 适用于需要显示圆形图片的场景,如用户头像等。 ### 主要的编程语言 CircleIma...

gitblog_09250的博客 645

Android 圆形图片 CircleImageView(Xfermode方式)

Android中实现圆形图片,总的说来有2种方法。 Xfermode方式,就是本文要讲的实现方式。 BitmapShader(着色器)和Matrix(矩阵)方式 第二种实现方式的代表作,就是Henning Dodenhof的开源项目https://github.com/hdodenhof/CircleImageView,会在下一篇文章中对其分析。 Android 圆形图片开源项目CircleIma

wlwh90的专栏 3416

CircleImageView解析

首先、它是继承自ImageView,给ImageView设置图片的方法就是setImageXXX,不管你是用JAVA代码设置,还是在XML里面用src,它最终还是调用JAVA的setImageXXX方法,在这些个方法的最后一定有一个invalidate的方法,让其调用onDraw。 CircleImageView的原理也是这样,声明一个mBitmap这个就是要带到CircleImageV

Android探索之路 1万+

CANN Lightning Indexer V2元数据算子

[📄 查看源码](https://link.gitcode.com/i/1fc4dcf4a7710684bd8bf11ed6a99464) ## 产品支持情况 | 产品 | 是否支持 | | :---------------------------------------

gitblog_09248的博客 464

uni-app如何生成海报图片

通过uni-app生成分享图海报,进行活动分享和转发

月落星河 6476
上一篇: 每日面试题分享,祝你剑指苍穹斩获Offer
下一篇: 用Flutter实现的无限滑动Banner
初壹十五a
博客等级 码龄8年 146粉丝 257原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值