Bitmap相关

1.介绍

Bitmap,即位图。它本质上就是一张图片的内容在内存中的表达形式

1、Bitmap.Config

Config是Bitmap的一个枚举内部类,它表示的就是每个像素点对ARGB通道值的存储方案。取值有以下四种:

ARGB_8888:这种方案就是上面所说的每个通道值采8bit来表示,每个像素点需要4字节的内存空间来存储数据。该方案图片质量是最高的,但是占用的内存也是最大的

ARGB_4444:这种方案每个通道都是4位,每个像素占用2个字节,图片的失真比较严重。一般不用这种方案。

RGB_565:这种方案RGB通道值分别占5、6、5位,但是没有存储A通道值,所以不支持透明度。每个像素点占用2字节,是ARGB_8888方案的一半。

ALPHA_8:这种方案不支持颜色值,只存储透明度A通道值,使用场景特殊,比如设置遮盖效果等。

比较分析:一般我们在ARGB_8888方式和RGB_565方式中进行选取:不需要设置透明度时,比如拍摄的照片等,RGB_565是个节省内存空间的不错的选择;既要设置透明度,对图片质量要求又高,就用ARGB_8888。

Bitmap工具类

质量压缩

public class BitmapUtil {
    /*
     * 质量压缩法:将图片文件压缩,压缩是耗时操作
     */
    public static void compressFile(CompressFileBean compressFileBean, CompressFileCallback compressFileCallback) {
        new CompressFileThread(compressFileBean, compressFileCallback).start();
    }
}

 /**
     * 压缩bitmap的执行线程
     */
    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();
            //将base64转成bitmap
            Bitmap bitmap = Base64Utils.base64ToBitmap(compressFileBean.getBase64());
            //判断是否要进行图片宽高进行修改缩放
            if (compressFileBean.getReqHeight()!=0&&compressFileBean.getReqWidth()!=0){
                int height =0;
                int weight =0;
                if (compressFileBean.getReqHeight()==0){
                    height =bitmap.getHeight();
                }else {
                    height=compressFileBean.getReqHeight();
                }
                if (compressFileBean.getReqWidth()==0){
                    weight =bitmap.getHeight();
                }else {
                    weight=compressFileBean.getReqWidth();
                }
                bitmap = setImgSize(bitmap,weight, height);
            }
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            // 从质量100开始压缩
            int quality = 100;
            //压缩格式选取JPEG就行了,quality,压缩精度尽量不要低于50,否则影响清晰度
            bitmap.compress(Bitmap.CompressFormat.JPEG, quality, byteArrayOutputStream);
            //开始循环压缩,当压缩至满足质量或者kb中一条时则不再压缩
            while (byteArrayOutputStream.toByteArray().length / 1024 > compressFileBean.getKb_max() && quality > compressFileBean.getQuality_max()) {
                // 循环判断如果压缩后图片是否大于kb_max kb,大于继续压缩,
                byteArrayOutputStream.reset();
                //质量每次减少10
                quality -= 10;
                bitmap.compress(Bitmap.CompressFormat.JPEG, quality, byteArrayOutputStream);
            }
            Bitmap finalBitmap = bitmap;
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    //压缩成功
                    compressFileCallback.onCompressFileFinished(finalBitmap);
                }
            });


        }

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

    }

    /**
     * 期望bitmap的参数的bean
     */
    public static class CompressFileBean {

        private int kb_max = 200;//压缩到多少KB,不能精确,只能<=kb_max
        private int quality_max = 50;//压缩精度,尽量>=50
        private int reqWidth;//期望的图片宽度
        private int reqHeight ;//期望的图片高度
        private String base64;


        public String getBase64() {
            return base64;
        }

        public void setBase64(String base64) {
            this.base64 = base64;
        }

        private CompressFileBean(Builder builder) {
            this.kb_max = builder.getKb_max();
            this.quality_max = builder.getQuality_max();
            this.reqWidth = builder.getReqWidth();
            this.reqHeight = builder.getReqHeight();
            this.base64 = builder.getBase64();
        }

        public static class Builder {
            private int kb_max = 100;//压缩到多少KB,不能精确,只能<=kb_max
            private int quality_max = 50;//压缩精度,尽量>=50
            private int reqWidth = 100;//期望的图片宽度
            private int reqHeight = 100;//期望的图片高度
            private String base64;

            public String getBase64() {
                return base64;
            }

            public Builder setBase64(String base64) {
                this.base64 = base64;
                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 int getKb_max() {
            return kb_max;
        }

        public int getQuality_max() {
            return quality_max;
        }

        public int getReqWidth() {
            return reqWidth;
        }

        public int getReqHeight() {
            return reqHeight;
        }
    }

    /**
     * bitmap 压缩回调
     */
    public  interface CompressFileCallback {
        //图片压缩成功
         void onCompressFileFinished(Bitmap bitmap);

        //图片压缩失败
         void onCompressFileFailed(String errorMsg);
    }

    /**
     * 
     * @param bm bitmap 位图
     * @param newWidth 图片宽度
     * @param newHeight 图片高度
     * @return bitmap 位图
     */
    public static Bitmap setImgSize(Bitmap bm, int newWidth, int newHeight) {
        // 获得图片的宽高.
        int width = bm.getWidth();
        int height = bm.getHeight();
        // 计算缩放比例.
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // 取得想要缩放的matrix参数.
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        // 得到新的图片.
        Bitmap newbm = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true);
        return newbm;
    }

bitmap 和base64互转

 /**
     * base64转为bitmap
     * @param base64Data
     * @return
     */
    public static Bitmap base64ToBitmap(String base64Data) {
        byte[] bytes = Base64.decode(base64Data, Base64.DEFAULT);
        return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
    }
   /**
     * bitmap转为base64 如果转JPEG后有黑底的话,可以尝试转PNG
     * @param bitmap
     * @param format bitmap转byte的图片类型  Bitmap.CompressFormat.JPEG  PNG  WEBP 三种
     * @return
     */
    public static String bitmapToBase64(Bitmap bitmap, Bitmap.CompressFormat format) {

        String result = null;
        ByteArrayOutputStream baos = null;
        try {
            if (bitmap != null) {
                baos = new ByteArrayOutputStream();
                bitmap.compress(format, 100, baos);

                baos.flush();
                baos.close();

                byte[] bitmapBytes = baos.toByteArray();
                result = Base64.encodeToString(bitmapBytes, Base64.DEFAULT);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (baos != null) {
                    baos.flush();
                    baos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

其他

  /**
     * 对View进行量测,布局后截图
     *
     * @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.RGB_565);
        Canvas canvas = new Canvas(bitmap);
        view.draw(canvas);
        return bitmap;
    }


    /**
     * 将图片按照某个角度进行旋转
     *
     * @param bm     需要旋转的图片
     * @param degree 旋转角度
     * @return 旋转后的图片
     */

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

        Bitmap returnBm = null;
        // 根据旋转角度,生成旋转矩阵
        Matrix matrix = new Matrix();
        matrix.postRotate(degree);
        try {

            // 将原始图片按照旋转矩阵进行旋转,并得到新的图片

            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;

    }

    /**
     * 裁剪
     *
     * @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;
    }

你可能感兴趣的:(Bitmap相关)