美文网首页
Bitmap相关

Bitmap相关

作者: 吐必南波丸 | 来源:发表于2021-12-15 13:33 被阅读0次

    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相关

          本文链接:https://www.haomeiwen.com/subject/eigufrtx.html