Android圖片的剪裁處理

jopen 10年前發布 | 42K 次閱讀 Android Android開發 移動開發

    /*

 * Copyright (C) 2015 www.amengsoft.org 
 *  
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 */  
package com.baojia.view;  

import java.io.File;  
import java.io.FileOutputStream;  
import java.util.concurrent.CountDownLatch;  

import android.app.Activity;  
import android.content.Context;  
import android.graphics.Bitmap;  
import android.graphics.Bitmap.CompressFormat;  
import android.graphics.Canvas;  
import android.graphics.Matrix;  
import android.graphics.PointF;  
import android.graphics.Rect;  
import android.graphics.RectF;  
import android.media.FaceDetector;  
import android.os.Handler;  

import com.ab.global.AbConstant;  
import com.ab.util.AbFileUtil;  
import com.ab.view.cropimage.HighlightView;  

/** 
 * 裁剪處理. 
 * @author LuKe 
 */  
public class CropImage{  

    /** The file local. */  
    public File FILE_LOCAL = null;  
    // Whether we are wait the user to pick a face.  
    /** The m waiting to pick. */  
    public boolean mWaitingToPick;   
    // Whether the "save" button is already clicked.  
    /** The m saving. */  
    public boolean mSaving;   

    /** The m crop. */  
    public HighlightView mCrop;  

    /** The m context. */  
    private Context mContext;  

    /** The m handler. */  
    private Handler mHandler;  

    /** The m image view. */  
    private CropImageView mImageView;  

    /** The m bitmap. */  
    private Bitmap mBitmap;  
    /** 
     * 裁切框寬和寬比 
     * **/  
    private float widthByHeight=1;  

    private int cropImgWidth=300,cropImgHeight=200;  

    /** 
     * Instantiates a new crop image. 
     * 
     * @param context the context 
     * @param imageView the image view 
     * @param handler the handler 
     */  
    public CropImage(Context context, CropImageView imageView,Handler handler,int cropImgWidth,int cropImgHeight){  
        mContext = context;  
        mImageView = imageView;  
        mImageView.setCropImage(this);  
        mHandler = handler;  
        this.cropImgWidth=cropImgWidth;  
        this.cropImgHeight=cropImgHeight;  
        widthByHeight=cropImgHeight/cropImgWidth;  
        //初始化圖片保存路徑  
        FILE_LOCAL = new File(AbFileUtil.getImageDownFullDir());  
        if(!FILE_LOCAL.exists()){  
            FILE_LOCAL.mkdirs();  
        }  
    }  

    /** 
     * 圖片裁剪. 
     * 
     * @param bm the bm 
     */  
    public void crop(Bitmap bm){  
        mBitmap = bm;  
        startFaceDetection();  
    }  

    /** 
     * Start rotate. 
     * 
     * @param d the d 
     */  
    public void startRotate(float d) {  
        if (((Activity)mContext).isFinishing()) {  
            return;  
        }  
        final float degrees = d;  
        final CountDownLatch latch = new CountDownLatch(1);  
        Runnable mRunnable =  new Runnable() {  
            public void run() {  
                mHandler.post(new Runnable() {  
                    public void run() {  
                        try{  
                            Matrix m = new Matrix();  
                            m.setRotate(degrees);  
                            Bitmap tb = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(), mBitmap.getHeight(),m,false);  
                            mBitmap = tb;  
                            mImageView.resetView(tb,cropImgWidth,cropImgHeight);  
                            if (mImageView.mHighlightViews.size() > 0) {  
                                mCrop = mImageView.mHighlightViews.get(0);  
                                mCrop.setFocus(true);  
                            }  
                        }catch (Exception e) {  
                        }  
                        latch.countDown();  
                    }  
                });  
                try {  
                    latch.await();  
                } catch (Exception e) {  
                    throw new RuntimeException(e);  
                }  
                //mRunFaceDetection.run();  
            }  
        };  
        new Thread(new BackgroundJob("", mRunnable, mHandler)).start();  
    }  

    /** 
     * Start face detection. 
     */  
    private void startFaceDetection() {  
        if (((Activity)mContext).isFinishing()) {  
            return;  
        }  
        Runnable mRunnable = new Runnable() {  
            public void run() {  
                final CountDownLatch latch = new CountDownLatch(1);  
                final Bitmap b = mBitmap;  
                mHandler.post(new Runnable() {  
                    public void run() {  
                        if (b != mBitmap && b != null) {  
                            mImageView.setImageBitmapResetBase(b, true);  
                            mBitmap.recycle();  
                            mBitmap = b;  
                        }  
                        if (mImageView.getScale() == 1.0f) {  
                            mImageView.center(true, true);  
                        }  
                        latch.countDown();  
                    }  
                });  
                try {  
                    latch.await();  
                } catch (Exception e) {  
                    throw new RuntimeException(e);  
                }  
                mRunFaceDetection.run();  
            }  
        };  
        new Thread(new BackgroundJob("", mRunnable, mHandler)).start();  
    }  

    /** 
     * 裁剪并保存. 
     * 
     * @return the bitmap 
     */  
    public Bitmap cropAndSave(){  
        final Bitmap bmp = onSaveClicked(mBitmap);  
        mImageView.mHighlightViews.clear();  
        return bmp;  
    }  

    /** 
     * 裁剪并保存. 
     * 
     * @param bm the bm 
     * @return the bitmap 
     */  
    public Bitmap cropAndSave(Bitmap bm){  
        final Bitmap bmp = onSaveClicked(bm);  
        mImageView.mHighlightViews.clear();  
        return bmp;  
    }  

    /** 
     * 取消裁剪. 
     */  
    public void cropCancel(){  
        mImageView.mHighlightViews.clear();  
        mImageView.invalidate();  
    }  

    /** 
     * On save clicked. 
     * 
     * @param bm the bm 
     * @return the bitmap 
     */  
    private Bitmap onSaveClicked(Bitmap bm) {  
        if (mSaving)  
            return bm;  

        if (mCrop == null) {  
            return bm;  
        }  

        mSaving = true;  

        Rect r = mCrop.getCropRect();  
        //int width = 360;     
        //int height = 360;    
        Bitmap croppedImage = Bitmap.createBitmap(cropImgWidth, cropImgHeight, Bitmap.Config.RGB_565);  
        Canvas canvas = new Canvas(croppedImage);  
        Rect dstRect = new Rect(0, 0, cropImgWidth, cropImgHeight);  
        canvas.drawBitmap(bm, r, dstRect, null);  
        return croppedImage;  
    }  

    /** 
     * Save to local. 
     * 
     * @param bitmap the bitmap 
     * @return the string 
     */  
    public String saveToLocal(Bitmap bitmap){  
        //需要裁剪后保存為新圖片  
        String mFileName = System.currentTimeMillis() + ".jpg";  
        String path = FILE_LOCAL+File.separator+mFileName;  
        try{  
            FileOutputStream fos = new FileOutputStream(path);  
            bitmap.compress(CompressFormat.JPEG, 85, fos);  
            fos.flush();  
            fos.close();  
        } catch (Exception e){  
            e.printStackTrace();  
            return null;  
        }  
        return path;  
    }  

    /** The m run face detection. */  
    Runnable mRunFaceDetection = new Runnable() {  
        float mScale = 1F;  
        Matrix mImageMatrix;  
        FaceDetector.Face[] mFaces = new FaceDetector.Face[3];  
        int mNumFaces;  

        // For each face, we create a HightlightView for it.  
        private void handleFace(FaceDetector.Face f) {  
            PointF midPoint = new PointF();  

            int r = ((int) (f.eyesDistance() * mScale)) * 2;  
            f.getMidPoint(midPoint);  
            midPoint.x *= mScale;  
            midPoint.y *= mScale;  

            int midX = (int) midPoint.x;  
            int midY = (int) midPoint.y;  

            HighlightView hv = new HighlightView(mImageView);  

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

            Rect imageRect = new Rect(0, 0, width, height);  

            RectF faceRect = new RectF(midX, midY, midX, midY);  

            faceRect.inset(-r, -r);  
            if (faceRect.left < 0) {  
                faceRect.inset(-faceRect.left, -faceRect.left);  
            }  

            if (faceRect.top < 0) {  
                faceRect.inset(-faceRect.top, -faceRect.top);  
            }  

            if (faceRect.right > imageRect.right) {  
                faceRect.inset(faceRect.right - imageRect.right, faceRect.right - imageRect.right);  
            }  

            if (faceRect.bottom > imageRect.bottom) {  
                faceRect.inset(faceRect.bottom - imageRect.bottom, faceRect.bottom - imageRect.bottom);  
            }  

            hv.setup(mImageMatrix, imageRect, faceRect, false, true);  

            mImageView.add(hv);  
        }  

        // Create a default HightlightView if we found no face in the picture.  
        private void makeDefault() {  
            HighlightView hv = new HighlightView(mImageView);  

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

            Rect imageRect = new Rect(0, 0, width, height);  

            // CR: sentences!  
            // make the default size about 4/5 of the width or height  
            int cropWidth = Math.min(width, height) * 4 / 5;  
            int cropHeight = cropWidth*cropImgHeight/cropImgWidth;  

            int x = (width - cropWidth) / 2;  
            int y = (height - cropHeight) / 2;  

            RectF cropRect = new RectF(x, y, x + cropWidth, y + cropHeight);  
            hv.setup(mImageMatrix, imageRect, cropRect, false, true);  
            mImageView.add(hv);  
        }  

        // Scale the image down for faster face detection.  
        private Bitmap prepareBitmap() {  
            if (mBitmap == null) {  
                return null;  
            }  

            // 256 pixels wide is enough.  
            // CR: F => f (or change all f to F).  
            if (mBitmap.getWidth() > 256) {  
                mScale = 256.0F / mBitmap.getWidth();   
            }  
            Matrix matrix = new Matrix();  
            matrix.setScale(mScale, mScale);  
            Bitmap faceBitmap = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), matrix, true);  
            return faceBitmap;  
        }  

        public void run() {  
            mImageMatrix = mImageView.getImageMatrix();  
            Bitmap faceBitmap = prepareBitmap();  

            mScale = 1.0F / mScale;  
            if (faceBitmap != null) {  
                FaceDetector detector = new FaceDetector(faceBitmap.getWidth(), faceBitmap.getHeight(), mFaces.length);  
                mNumFaces = detector.findFaces(faceBitmap, mFaces);  
            }  

            if (faceBitmap != null && faceBitmap != mBitmap) {  
                faceBitmap.recycle();  
            }  

            mHandler.post(new Runnable() {  
                public void run() {  
                    mWaitingToPick = mNumFaces > 1;  
                    makeDefault();  
                    mImageView.invalidate();  
                    if (mImageView.mHighlightViews.size() > 0) {  
                        mCrop = mImageView.mHighlightViews.get(0);  
                        mCrop.setFocus(true);  
                    }  

                    if (mNumFaces > 1) {  
                    }  
                }  
            });  
        }  
    };  

    /** 
     * The Class BackgroundJob. 
     */  
    public class BackgroundJob implements Runnable{  

        /** The message. */  
        private String message;  

        /** The m job. */  
        private Runnable mJob;  

        /** The m handler. */  
        private Handler mHandler;  

        /** 
         * Instantiates a new background job. 
         * 
         * @param m the m 
         * @param job the job 
         * @param handler the handler 
         */  
        public BackgroundJob(String m, Runnable job, Handler handler){  
            message = m;  
            mJob = job;  
            mHandler = handler;  
        }  

        /** 
         * 描述:TODO. 
         * 
         * @see java.lang.Runnable#run() 
         * @author: zhaoqp 
         * @date:2013-6-17 上午9:04:47 
         * @version v1.0 
         */  
        public void run(){  
            final CountDownLatch latch = new CountDownLatch(1);  
            mHandler.post(new Runnable() {  
                public void run() {  
                    try{  
                        mHandler.sendMessage(mHandler.obtainMessage(AbConstant.SHOW_PROGRESS));  
                    }catch (Exception e) {  
                    }  
                    latch.countDown();  
                }  
            });  
             try {  
                 latch.await();  
             } catch (Exception e) {  
                 throw new RuntimeException(e);  
             }  
            try {  
                mJob.run();  
            }catch (Exception e) {  
                e.printStackTrace();  
            }finally{  
                mHandler.sendMessage(mHandler.obtainMessage(AbConstant.REMOVE_PROGRESS));  
            }  
        }  
    }  
}  </pre><br />
 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!