欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android开发之头像智能裁剪

程序员文章站 2022-03-24 22:22:34
...

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

Android开发之头像智能裁剪

圆角头像采用 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了,以上为全部代码了!