Android开发之头像智能裁剪

Android ------ 开源的Modnet算法实现抠图和更换背景 Portrait Matting (sight-x.cn) 飞桨PaddlePaddle-源于产业实践的开源深度学习平台 GitHub - PaddlePaddle/PaddleSeg at develop 阅读详情

本篇主要是记录头像智能裁剪,如果图片含有人头像就智能提取头像,没有就按照默认scaleType裁剪。

圆角头像采用 circleimageview 开源库

compile ‘de.hdodenhof:circleimageview:2.1.0’

网络图片加载这里采用 Glide

compile ‘com.github.bumptech.glide:glide:3.7.0’

人脸识别抠图辅助类 FaceHelper


import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.PointF;
import android.media.FaceDetector;
import android.util.Log;

import de.hdodenhof.circleimageview.CircleImageView;

public final class FaceHelper {

    public static void clipFacePhotoBitmap(final Activity activity, final CircleImageView circleImageView, final Bitmap bitmap){

        new Thread(new Runnable() {
            @Override
            public void run() {
                Log.e("time","face clip time start:"+System.currentTimeMillis()+"****");
                Bitmap faceBitmap = genFaceBitmap(bitmap);
                if(faceBitmap==null){
                    faceBitmap = bitmap;
                }
                final Bitmap finalFaceBitmap = faceBitmap;
                activity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        circleImageView.setImageBitmap(finalFaceBitmap);
                        Log.e("time","face clip time end: "+System.currentTimeMillis()+"****");
                    }
                });
            }
        }).start();
    }
    public static Bitmap genFaceBitmap(Bitmap sourceBitmap) {

        if (!checkBitmap(sourceBitmap)) {
            return null;
        }

        Bitmap cacheBitmap = sourceBitmap.copy(Bitmap.Config.RGB_565, false);

        sourceBitmap = null;

        int cacheWidth = cacheBitmap.getWidth();
        int cacheHeight = cacheBitmap.getHeight();
        if (cacheWidth % 2 != 0) {
            if (0 == cacheWidth - 1) {
                return null;
            }
            final Bitmap localCacheBitmap = Bitmap.createBitmap(cacheBitmap, 0,
                    0, cacheWidth - 1, cacheHeight);
            cacheBitmap.recycle();
            cacheBitmap = localCacheBitmap;
            --cacheWidth;
        }

        final FaceDetector.Face[] faces = new FaceDetector.Face[1];
        final int facefound = new FaceDetector(cacheWidth, cacheHeight, 1)
                .findFaces(cacheBitmap, faces);
        if (0 == facefound) {
            return null;
        }

        final PointF p = new PointF();
        faces[0].getMidPoint(p);

        final int faceX = (int) p.x;
        final int faceY = (int) p.y;

        int startX, startY, width, height;
        if (faceX <= cacheWidth - faceX) {
            startX = 0;
            width = faceX * 2;
        } else {
            startX = faceX - (cacheWidth - faceX);
            width = (cacheWidth - faceX) * 2;
        }
        if (faceY <= cacheHeight - faceY) {
            startY = 0;
            height = faceY * 2;
        } else {
            startY = faceY - (cacheHeight - faceY);
            height = (cacheHeight - faceY) * 2;
        }

        final Bitmap result = Bitmap.createBitmap(cacheBitmap, startX, startY,
                width, height);
        cacheBitmap.recycle();
        return result;
    }

    private static boolean checkBitmap(final Bitmap bitmap) {
        if (null == bitmap || bitmap.isRecycled()) {
            return false;
        }
        if (0 == bitmap.getWidth() || 0 == bitmap.getHeight()) {
            return false;
        }
        return true;
    }
}

测试demo xml文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:background="#1a87be"
        >

        <de.hdodenhof.circleimageview.CircleImageView
            android:id="@+id/circleImageView"
            android:layout_width="80dp"
            android:layout_centerInParent="true"
            android:layout_height="80dp"
            android:src="@drawable/icon_cateye_default_photo"
            app:civ_border_color="#55C4FC"
            app:civ_border_width="2dp" />
    </RelativeLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:orientation="horizontal"
        android:layout_height="200dp">

        <ImageView
            android:id="@+id/normal"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_margin="20dp"
            android:layout_weight="1"
            android:src="@drawable/url_normal" />

        <ImageView
            android:id="@+id/photo"
            android:layout_width="0dp"
            android:src="@drawable/url_photo"
            android:layout_height="match_parent"
            android:layout_margin="20dp"
            android:layout_weight="1"/>
    </LinearLayout>

</LinearLayout>

测试代码 MainActivity.class


import android.graphics.Bitmap;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.SimpleTarget;

import de.hdodenhof.circleimageview.CircleImageView;

public class MainActivity extends AppCompatActivity {

    public static final String URL_NORMAL = "http://tgi12.jia.com/119/917/19917355.jpg";

    public static final String URL_PHOTO = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1524534441&di=c4bf6ab9e77c9ceda8283f43d188f04e&imgtype=jpg&er=1&src=http%3A%2F%2Fimg.pconline.com.cn%2Fimages%2Fupload%2Fupc%2Ftx%2Fitbbs%2F1603%2F03%2Fc40%2F18838489_1457005978542_mthumb.jpg";

    private CircleImageView circleImageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        circleImageView = (CircleImageView)findViewById(R.id.circleImageView);

        findViewById(R.id.normal).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Glide.with(getApplicationContext()).load(URL_NORMAL).asBitmap().into(new SimpleTarget<Bitmap>() {
                    @Override
                    public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
                        FaceHelper.clipFacePhotoBitmap(MainActivity.this,circleImageView,resource);
                    }
                });
            }
        });

        findViewById(R.id.photo).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Glide.with(getApplicationContext()).load(URL_PHOTO).asBitmap().into(new SimpleTarget<Bitmap>() {
                    @Override
                    public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
                        FaceHelper.clipFacePhotoBitmap(MainActivity.this,circleImageView,resource);
                    }
                });
            }
        });
    }
}

亲门,这次真没有demo了,以上为全部代码了!

Android 之 一键抠图,抠人像 Android 之 一键抠图,佐糖API 抠人像,超简单,唯一的缺点就是就是要花钱 阅读详情

相关推荐

微信小程序头像裁剪优化技巧:如何用image-cropper提升用户体验

本文详细介绍了如何利用image-cropper插件优化微信小程序的头像裁剪功能,提升用户体验。从基础集成到高级优化,包括视觉引导设计、手势操作优化和性能提升策略,帮助开发者实现媲美原生应用的流畅裁剪体验。

weixin_30342209的博客 332

Android 设置头像 - 裁剪及圆形头像

通过裁剪和圆形头像的实现更加深入的对ActivityResultLauncher进行了学习,并在实现的过程中对Intent有了更加深入的思考,如果本文内容存在问题欢迎各位大佬进行斧正。总结本文内容。Ucrop工具实现图片裁剪Intent系统默认裁剪实现类intent深入思考Gilde圆形图片的实现。

zyppxx的博客 2313

微信姓氏头像框小程序源码:复古/酷炫/清纯多风格模板,支持短语自由搭配+流量主广告接入

一套可直接上手的微信姓氏头像框小程序源码,内置复古、酷炫、清纯等多套视觉模板,用户输入姓氏再配上离职语、祝福语或个性签名等短语,就能一键生成专属头像框。不用买服务器、不用备案域名,用微信开发者工具导入就能调试运行;压缩包里已配好微信平台认可的合法域名清单,按文档提示简单配置即可提交审核。源码经过实际修复,解决了旧版卡在验证页无法出图的问题,现在能稳定跳过验证直接生成图片。功能模块分工明确:we-cropper负责头像裁剪,upload.js处理图片上传,index页面承载核心交互,fenleib等文件夹管理

gin88的博客 262

android 头像选择,裁剪全套解决方案,你值得拥有!

头像选取,裁切,上传等功能基本上是现在每个app必备的功能,实现起来倒是不复杂,确是要花点时间。恰好前几天把这个功能做完了,本着不重复造轮子的原则,提供一整套解决方案,希望给能用到的小伙伴。 首先放头像必须得有一个控件,我这里用的 CircleImageView implementation 'de.hdodenhof:circleimageview:2.1.0' 然后是点击控件弹出选择框...

abs625的博客 6485

Android应用中实现更换头像功能完整技术指南

简介:在Android应用开发中,更换头像是一项常见且重要的功能,广泛应用于社交、个人中心等场景。该功能涵盖图片选择(相册/拍照)、运行时权限申请、图片裁剪与压缩、图像加载优化、本地文件存储、数据库更新及UI同步显示等多个环节。本文详细解析实现该功能的核心技术流程,帮助开发者掌握从用户操作到数据持久化的完整链路,并提升适配性、稳定性和用户体验。

weixin_30021053的博客 949

Android图片裁剪与人脸识别实战示例项目

在Android图像处理场景中,系统级的裁剪服务虽然便捷,但其高度依赖设备厂商预装应用的支持,导致在多品牌碎片化环境下表现极不稳定。为确保用户体验的一致性与功能完整性,越来越多的应用选择构建自定义图片裁剪界面,以完全掌控裁剪流程、交互方式和视觉呈现。本章将深入探讨如何从零开始设计并实现一个高性能、高可用性的自定义裁剪组件,涵盖UI架构搭建、触摸逻辑控制、坐标变换建模、内存优化策略以及结果输出机制。

weixin_34725745的博客 1070

编译MediaPipe自分割GPU模块为aar包,实现抠图替换背景

实现背景替换功能,目前搜到的MediaPipe解决方案都不是GPU方式(自己手机测试,非GPU背景替换时的性能参数CPU使用20%左右、内存120M左右、FPS20左右、Detect time:30-50m),下边是编译GPU方式(GPU方式可以大大减少CPU负担,自测发现CPU使用10%左右)实现的AAR,为了方便编译,我这边使用windows下的子系统wsl。...

weixin_41605683的博客 1255

多人脸裁剪人脸裁剪 人脸检测

最近用到人脸识别技术,有个需求是多人脸图片的时候需要一个一个把人脸裁剪出来,以便获取人脸的图片,从而用其获取单人脸的特征

Android-Image-Cropper网络图片处理:从URL直接裁剪的完整方案

在移动应用开发中,图片裁剪是一个常见但复杂的任务,特别是当需要处理来自网络的图片时。Android-Image-Cropper作为一款专为Android平台优化的图片裁剪库,提供了从URL直接裁剪网络图片的完整解决方案。这个强大的库不仅支持本地图片,还能高效处理网络图片,让你的应用在图片处理方面更加专业和用户友好。 ## 为什么需要网络图片裁剪功能? 🖼️ 传统的图片裁剪流程通常需要先将网络

gitblog_00262的博客 1039

哨兵一号数据下载

哨兵1号数据的下载过程

weixin_59617499的博客 5134

精确时钟同步协议ptp/IEEE-1588v2协议-------(1)简介

ptp, 1588V2, IEEE-1588, 精确时钟同步协议

meihualing的专栏 5352

Android-Image-Cropper扩展功能:自动缩放与智能对齐终极指南

Android-Image-Cropper是一个功能强大的Android图片裁剪库,专为相机和相册应用优化。在众多优秀功能中,自动缩放和智能对齐功能能够显著提升用户体验,让图片裁剪变得更加智能和高效。本文将深入解析这两个核心扩展功能的使用方法和配置技巧。🎯 ## 自动缩放功能详解 自动缩放功能是Android-Image-Cropper的一大亮点,它能够智能地调整裁剪框的大小和位置,确保裁剪

gitblog_00587的博客 869

一文读懂Cache一致性原理

本文介绍了为什么需要维护cache一致性、一致性协议的本质和类别,以及如何设计一致性协议。

W1Z1Q的专栏 6832

FGD:提升目标检测性能的利器

FGD:提升目标检测性能的利器 项目介绍 FGD(Focal and Global Knowledge Distillation for Detectors)是一个基于知识蒸馏技术的开源项目,旨在通过蒸馏方法提升目标检测模型的性能。该项目在CVPR 2022上发表的论文《Focal and Global Knowledge Distillation for Detectors》中首次提出,并已在G...

gitblog_00085的博客 507

Simulink仿真避坑指南:如何设置步长、powergui和模块采样时间才能让控制周期更稳定

本文深入解析Simulink仿真中步长、powergui和模块采样时间的协同配置方法,帮助工程师解决控制周期不稳定问题。通过实际案例和参数调优技巧,指导用户精准设置仿真参数,确保电机控制、电力电子系统等工业仿真结果的可靠性。

weixin_42524762的博客 417

医学影像处理实战:如何用Python+SimpleITK搞定DICOM/NIfTI重采样(附完整代码)

本文详细介绍了如何使用Python和SimpleITK库实现医学影像(DICOM/NIfTI格式)的智能重采样技术。通过实战代码演示,帮助读者掌握医学图像处理中的关键步骤,包括环境搭建、数据准备、核心算法实现和质量验证,解决医学AI领域中的影像标准化难题。

linux的博客 981

Android图片裁剪终极指南:使用Android Image Cropper实现专业级裁剪功能

想要为你的Android应用添加专业级的图片裁剪功能吗?Android Image Cropper是一个专门为相机和相册优化的图片裁剪库,能够让你的应用具备与Instagram、Snapseed等专业应用相媲美的裁剪体验。这个开源库提供了丰富的配置选项和流畅的用户交互,是Android开发者的必备工具。 ## 🎯 为什么选择Android Image Cropper? Android Ima

gitblog_00766的博客 740

SST专题(2-5)MMC-SST 输入级的环流抑制

本文研究了模块化多电平换流器(MMC)的数学模型及其环流抑制控制方法。首先建立了MMC等效电路模型,推导了桥臂电流方程和虚拟电动势表达式,提出通过控制桥臂电压修正量来调节内部电流而不影响外部特性。针对MMC特有的二倍频负序环流问题,设计了基于负序旋转坐标变换的环流抑制控制器(CCSC),将时变环流转换为直流量进行控制。通过比例-积分调节和电压前馈补偿,生成内部不平衡压降参考值,最终形成包含功率控制和环流抑制的整体控制结构。仿真结果表明该方法能有效抑制内部环流,同时保持系统稳定运行。

嵌入式老牛的博客 535

终极指南:Android图片裁剪库让照片编辑变得如此简单!

还在为Android应用中的图片裁剪功能而烦恼吗?🤔 今天我要向你推荐一款强大的Android图片裁剪库——Android Image Cropper,它能让你的照片编辑体验变得前所未有的简单高效! Android Image Cropper是一个专为Android平台优化的图片裁剪解决方案,特别针对相机和图库场景进行了深度优化。无论你是要开发社交应用、照片编辑软件,还是简单的头像上传功能,这

gitblog_00461的博客 851

人工智能之数学基础:弄懂数学本质,让我们不再害怕数学

数学的用途远远超过了人们的想象,甚至无处不在,任何领域都需要用到数学知识,人工智能也不例外。我将尽可能地将数学知识和机器学习算法相结合,让大家知道这些数学知识咋人工智能领域中的应用,使得数学的学习不会过于枯燥,同时也帮助大家扫清在学习算法过程中的数学障碍。除此之外,我还希望帮助大家建立一种不一样的数学思维,不再将数学看成是符号的演算、公式的推导,而是将数学看成是一种描述这个世界的工具,这样你就会发现这个世界处处有数学。当我们面对问题的时候,你是否会对问题进行抽象,然后通过数学来解决问题?

huanfeng_AI的博客 629

手把手教你玩转CPU微架构--​第三章:乱序执行的“魔法”——如何让指令“插队”提升效率​​3.4 动手实验:用Gem5模拟器分析乱序执行对IPC的提升(对比顺序执行)

摘要:本章通过Gem5模拟器对比乱序执行(O3CPU)和顺序执行的性能差异,实验采用SPECCPU2017和PARSEC3.0基准测试,配置7级流水线、4指令/周期发射宽度及多级缓存。结果显示,乱序执行平均提升IPC超过100%,关键因素包括动态指令调度、缓存命中率提升(L1达92%)和TAGE分支预测(准确率95%)。优化方向包括增大指令缓存和发射队列深度。实验验证了乱序执行在减少流水线停顿和提升吞吐量方面的显著优势。

MHD0815的博客 165

终极指南:如何使用Android Image Cropper实现专业级图片裁剪功能

Android Image Cropper是一个专为Android平台设计的强大图片裁剪库,经过优化后特别适合相机和图库场景使用。这个开源库提供了完整的图片裁剪解决方案,让开发者能够轻松实现专业级的图片处理功能。 ## 🎯 为什么选择Android Image Cropper? Android Image Cropper具有四大核心优势: - **功能强大**:支持缩放、旋转、多源输入 -

gitblog_00313的博客 1067

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Textual 样式指南:margin 属性详解与源码级实现原理

`margin` 是 Textual 中用于在部件(widget)四周添加间距的核心样式,负责控制部件与其相邻元素之间的留白。本文基于 [margin 官方参考文档](https://link.gitcode.com/i/70bffabb897502a00280f97b54c2b412) 展开,结合 [CSS 解析源码](https://link.gitcode.com/i/67fa9eb7533

gitblog_00214的博客 360

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

如何使用Masaccio:打造智能人脸检测与裁剪的Android应用

Masaccio是一个强大的Android开源库,提供了智能人脸检测与裁剪功能,能自动识别图片中的人脸并优化裁剪效果,帮助开发者轻松实现专业级的图像处理功能。无论是社交应用、摄影APP还是需要用户头像处理的场景,Masaccio都能显著提升图片展示效果。 ## 📸 什么是Masaccio? Masaccio是由Subito.it开发的Android库,核心功能是通过`MasaccioImag

gitblog_00705的博客 431

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

5大理由让你爱上这款Android图片裁剪库![特殊字符]

在移动应用开发中,Android图片处理功能是提升用户体验的关键环节。今天为大家推荐一款专为Android平台设计的开源裁剪工具——Android Image Cropper,它不仅能满足基础裁剪需求,更为开发者提供了丰富的定制选项。 ## 🔥 为什么选择这个库? **1. 极致性能优化** ✨ 这款Android图片裁剪库经过精心优化,采用异步处理机制和智能矩阵运算,大幅降低内存占用,确保

gitblog_00102的博客 513

Android图片裁剪库终极指南:深入源码架构与设计模式分析

Android图片裁剪是移动应用开发中的核心功能之一,无论是头像设置、图片编辑还是内容分享,都需要强大而灵活的裁剪工具。Android-Image-Cropper作为一款专门为Android设计的图片裁剪库,提供了完整的解决方案。本文将深入分析该库的源码架构、设计模式实现,帮助你全面理解这个强大的工具。🔍 ## 架构概览与核心模块设计 Android-Image-Cropper采用分层架构设

gitblog_01199的博客 1083
上一篇: Android开发之Zip下载解压
下一篇: 华为推送的文档就是垃圾垃圾垃圾!
AnalyzeSystem
博客等级 码龄11年 204粉丝 114原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值