Android开发之头像智能裁剪
程序员文章站
2022-03-24 22:22:34
...
本篇主要是记录头像智能裁剪,如果图片含有人头像就智能提取头像,没有就按照默认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了,以上为全部代码了!
上一篇: 小程序中上传头像裁剪
下一篇: wpf 加载gif
推荐阅读
-
Android开发之瀑布流控件的实现与使用方法示例
-
Android 媒体开发之MediaPlayer状态机接口方法实例解析
-
Android UI设计与开发之仿人人网V5.9.2最新版引导界面
-
Android开发之自带下载器DownloadManager的使用示例代码
-
android开发之蜂鸣提示音和震动提示的实现原理与参考代码
-
android开发之横向滚动/竖向滚动的ListView(固定列头)
-
Android编程开发之性能优化技巧总结
-
Android快速开发之定制BaseTemplate
-
Android开发之Socket通信传输简单示例
-
Android UI设计与开发之ViewPager仿微信引导界面以及动画效果