BitmapUtils

public class BitmapUtils {
    private BitmapUtils() {
    }

    //可以直接將網(wǎng)絡(luò)連接得到的輸入流讀取到字節(jié)流,壓縮為bitmpa
    public static Bitmap decodeBitmapFromBytes(byte[] data, int reqWidth, int reqHeight) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeByteArray(data, 0, data.length, options);
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeByteArray(data, 0, data.length, options);
    }

    /*
     * 計(jì)算采樣率
     */
    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {

            final int halfHeight = height / 2;
            final int halfWidth = width / 2;
            while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }

        return inSampleSize;
    }

    /**
     * 裁剪
     *
     * @param bitmap 原圖
     * @return 裁剪后的圖像
     */
    public static Bitmap cropBitmap(Bitmap bitmap, float hRatioW) {
        int w = bitmap.getWidth(); // 得到圖片的寬,高
        int h = bitmap.getHeight();
        return Bitmap.createBitmap(bitmap, 0, 0, w, (int) (w * hRatioW), null, false);
    }

    /**
     * 按比例縮放圖片
     *
     * @param origin 原圖
     * @param ratio  比例
     * @return 新的bitmap
     */
    public static Bitmap scaleBitmap(Bitmap origin, float ratio) {
        if (origin == null) {
            return null;
        }
        int width = origin.getWidth();
        int height = origin.getHeight();
        Matrix matrix = new Matrix();
        matrix.preScale(ratio, ratio);
        Bitmap newBM = Bitmap.createBitmap(origin, 0, 0, width, height, matrix, false);
        return newBM;
    }

    /*
     * 質(zhì)量壓縮法:將圖片文件壓縮,壓縮是耗時(shí)操作
     */
    public static void compressFile(CompressFileBean compressFileBean, CompressFileCallback compressFileCallback) {
        new CompressFileThread(compressFileBean, compressFileCallback).start();
    }
    /*
     * 由file轉(zhuǎn)bitmap
     */

    public static Bitmap decodeBitmapFromFilePath(String path, int reqWidth, int reqHeight) {

        // First decode with inJustDecodeBounds=true to check dimensions
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;//如此,無法decode bitmap
        BitmapFactory.decodeFile(path, options);

        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;//如此,方可decode bitmap

        return BitmapFactory.decodeFile(path, options);
    }

    /**
     * 根據(jù)路徑 創(chuàng)建文件
     *
     * @param pathFile
     * @return
     * @throws IOException
     */
    private static File createFile(String pathFile) throws IOException {
        File fileDir = new File(pathFile.substring(0, pathFile.lastIndexOf(File.separator)));
        File file = new File(pathFile);
        if (!fileDir.exists()) fileDir.mkdirs();
        if (!file.exists()) file.createNewFile();
        return file;
    }
    /**
     * 讀取圖片的旋轉(zhuǎn)的角度
     *
     * @param path 圖片絕對(duì)路徑
     * @return 圖片的旋轉(zhuǎn)角度
     */

    public static int getBitmapDegree(String path) {

        int degree = 0;

        try {

            // 從指定路徑下讀取圖片,并獲取其EXIF信息

            ExifInterface exifInterface = new ExifInterface(path);

            // 獲取圖片的旋轉(zhuǎn)信息

            int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,

                    ExifInterface.ORIENTATION_NORMAL);

            switch (orientation) {

                case ExifInterface.ORIENTATION_ROTATE_90:

                    degree = 90;

                    break;

                case ExifInterface.ORIENTATION_ROTATE_180:

                    degree = 180;

                    break;

                case ExifInterface.ORIENTATION_ROTATE_270:

                    degree = 270;

                    break;

            }

        } catch (IOException e) {

            e.printStackTrace();

        }

        return degree;

    }
    /**
     * 將圖片按照某個(gè)角度進(jìn)行旋轉(zhuǎn)
     *
     * @param bm     需要旋轉(zhuǎn)的圖片
     * @param degree 旋轉(zhuǎn)角度
     * @return 旋轉(zhuǎn)后的圖片
     */

    public static Bitmap rotateBitmapByDegree(Bitmap bm, int degree) {

        Bitmap returnBm = null;


        // 根據(jù)旋轉(zhuǎn)角度,生成旋轉(zhuǎn)矩陣

        Matrix matrix = new Matrix();

        matrix.postRotate(degree);

        try {

            // 將原始圖片按照旋轉(zhuǎn)矩陣進(jìn)行旋轉(zhuǎn),并得到新的圖片

            returnBm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);

        } catch (OutOfMemoryError e) {

        }

        if (returnBm == null) {

            returnBm = bm;

        }

        if (bm != returnBm) {

            bm.recycle();

        }

        return returnBm;

    }
    /**
     * 對(duì)View進(jìn)行量測(cè),布局后截圖
     *
     * @param view
     * @return
     */

    public static Object[] captureViewToBitmap(View view) {

        view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));


        int width = view.getMeasuredWidth();
        int height = view.getMeasuredHeight();
        view.layout(0, 0, width, height);


        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444);

        Canvas canvas = new Canvas(bitmap);
        view.draw(canvas);

        Object[] objects = new Object[3];
        objects[0] = bitmap;
        objects[1] = width;
        objects[2] = height;
        return objects;
    }

    /**
     * 對(duì)View進(jìn)行量測(cè),布局后截圖
     *
     * @param view
     * @return
     */

    public static Bitmap captureViewToBitmap(View view, int reqWidth, int reqHeight) {

        view.layout(0, 0, reqWidth, reqHeight);

        Bitmap bitmap = Bitmap.createBitmap(reqWidth, reqHeight, Bitmap.Config.ARGB_4444);
//        CYLogUtils.log("bitmap原始width", bitmap.getWidth());
//        CYLogUtils.log("bitmap原始height", bitmap.getHeight());
        Canvas canvas = new Canvas(bitmap);
        view.draw(canvas);

        return bitmap;
    }
    /*
   壓縮bitmap,會(huì)被壓縮到指定寬高
    */
    public static Bitmap compressBitmap(Bitmap bitmap, int reqWidth, int reqHeight) {

        return Bitmap.createScaledBitmap(bitmap, reqWidth, reqHeight, true);
    }
    private static class CompressFileThread extends Thread {
        private Handler handler_deliver = new Handler(Looper.getMainLooper());
        private CompressFileBean compressFileBean;
        private CompressFileCallback compressFileCallback;

        public CompressFileThread(CompressFileBean compressFileBean, CompressFileCallback compressFileCallback) {
            this.compressFileBean = compressFileBean;
            this.compressFileCallback = compressFileCallback;
        }

        @Override
        public void run() {
            super.run();
            final Bitmap bitmap = decodeBitmapFromFilePath(compressFileBean.getPathSource(), compressFileBean.getReqWidth(), compressFileBean.getReqHeight());

            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            int quality = 80;
            //壓縮格式選取JPEG就行了,quality,壓縮精度盡量不要低于50,否則影響清晰度
            bitmap.compress(Bitmap.CompressFormat.JPEG, quality, byteArrayOutputStream);

            while (byteArrayOutputStream.toByteArray().length / 1024 > compressFileBean.getKb_max() && quality > compressFileBean.getQuality_max()) {
                // 循環(huán)判斷如果壓縮后圖片是否大于kb_max kb,大于繼續(xù)壓縮,
                byteArrayOutputStream.reset();
                quality -= 10;
                bitmap.compress(Bitmap.CompressFormat.JPEG, quality, byteArrayOutputStream);
            }
            try {
                final File fileCompressed = createFile(compressFileBean.getPathCompressed());
                FileOutputStream fileOutputStream = new FileOutputStream(fileCompressed);
                fileOutputStream.write(byteArrayOutputStream.toByteArray());//寫入目標(biāo)文件
                fileOutputStream.flush();
                fileOutputStream.close();
                byteArrayOutputStream.close();
                if (fileCompressed != null && fileCompressed.length() > 0)
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            //壓縮成功
                            compressFileCallback.onCompressFileFinished(fileCompressed, bitmap);
                        }
                    });
            } catch (final Exception e) {
                e.printStackTrace();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        //壓縮失敗
                        compressFileCallback.onCompressFileFailed("壓縮圖片文件失敗" + e.getMessage());
                    }
                });
            }

        }

        private void runOnUiThread(Runnable run) {
            handler_deliver.post(run);
        }

    }

    public static class CompressFileBean {
        private String pathSource;//原圖文件路徑
        private String pathCompressed;//壓縮后的圖片文件路徑
        private int kb_max = 1000;//壓縮到多少KB,不能精確,只能<=kb_max
        private int quality_max = 80;//壓縮精度,盡量>=50
        private int reqWidth = 1000;//期望的圖片寬度
        private int reqHeight = 1000;//期望的圖片高度

        private CompressFileBean(Builder builder) {
            this.pathSource = builder.getFileSource();
            this.pathCompressed = builder.getFileCompressed();
            this.kb_max = builder.getKb_max();
            this.quality_max = builder.getQuality_max();
            this.reqWidth = builder.getReqWidth();
            this.reqHeight = builder.getReqHeight();
        }

        public static class Builder {
            private String pathSource;//原圖文件路徑
            private String pathCompressed;//壓縮后的圖片文件路徑
            private int kb_max = 1000;//壓縮到多少KB,不能精確,只能<=kb_max
            private int quality_max = 80;//壓縮精度,盡量>=50
            private int reqWidth = 1000;//期望的圖片寬度
            private int reqHeight = 1000;//期望的圖片高度

            public String getFileSource() {
                return pathSource;
            }

            public Builder setFileSource(String pathSource) {
                this.pathSource = pathSource;
                return this;
            }

            public String getFileCompressed() {
                return pathCompressed;
            }

            public Builder setFileCompressed(String pathCompressed) {
                this.pathCompressed = pathCompressed;
                return this;


            }

            public int getKb_max() {
                return kb_max;
            }

            public Builder setKb_max(int kb_max) {
                this.kb_max = kb_max;
                return this;
            }

            public int getQuality_max() {
                return quality_max;
            }

            public Builder setQuality_max(int quality_max) {
                this.quality_max = quality_max;
                return this;
            }

            public int getReqWidth() {
                return reqWidth;
            }

            public Builder setReqWidth(int reqWidth) {
                this.reqWidth = reqWidth;
                return this;
            }

            public int getReqHeight() {
                return reqHeight;
            }

            public Builder setReqHeight(int reqHeight) {
                this.reqHeight = reqHeight;
                return this;
            }

            public CompressFileBean build() {
                return new CompressFileBean(this);
            }
        }

        public String getPathSource() {
            return pathSource;
        }

        public String getPathCompressed() {
            return pathCompressed;
        }

        public int getKb_max() {
            return kb_max;
        }

        public int getQuality_max() {
            return quality_max;
        }

        public int getReqWidth() {
            return reqWidth;
        }

        public int getReqHeight() {
            return reqHeight;
        }
    }

    public static interface CompressFileCallback {
        //圖片壓縮成功
        public void onCompressFileFinished(File file, Bitmap bitmap);
        //圖片壓縮失敗
        public void onCompressFileFailed(String errorMsg);
    }
}


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容