Android开发探索android面试录Android之旅

Android 图片压缩

2017-11-29  本文已影响119人  Android师哥
night_rain.png

Android中图片压缩一般有两种方式,一种是通过改变图片的尺寸来改变图片的大小,另一种是通过改变图片像素的质量来改变图片的大小。第一种方式会直接改变Bitmap大小,也就是图片的宽高尺寸改变。第二种方式是改变了图片中像素的质量,本身的尺寸没有变化,但是体积确发生了变化!

    /**
     * 将本地路径转化为Bitmap
     *
     * @param path 本地路径
     * @return 返回本地资源的Bitmap
     */
    private Bitmap loadFile(String path) {
        File mFile = new File(path);
        Bitmap mBitmap = null;
        //判读文件是否存在
        if (mFile.exists()) {
            BitmapFactory.Options mOptions = new BitmapFactory.Options();
            //设置只加载尺寸资源
            mOptions.inJustDecodeBounds = true;
            //设置资源
            BitmapFactory.decodeFile(path, mOptions);
            //图片加载缩方处理
            coundScale(mOptions);
            //设置加载资源模式
            mOptions.inJustDecodeBounds = false;
            //设置资源
            mBitmap = BitmapFactory.decodeFile(path, mOptions);
        }
        return mBitmap;
    }


    /**
     * 计算缩放比例,防止OOM
     *
     * @param opeions BitmapFactory.Options
     */
    private void coundScale(BitmapFactory.Options opeions) {
        if (opeions != null) {
            //原图的尺寸
            int orginalWidht = opeions.outWidth;
            int orginalHieght = opeions.outHeight;
            //如果图片尺寸大于一定尺寸的时候进行缩放
            if (orginalWidht > 1080 || orginalHieght > 1920) {
                //缩小倍数
                int scale = 1;

                if (orginalWidht > orginalHieght) {
                    //长图片的时候(以宽度为基准缩小)
                    scale = orginalWidht / 1080;
                } else if (orginalWidht < orginalHieght) {
                    //高图的时候(以高度为基准缩小)
                    scale = orginalHieght / 1920;
                } else {
                    //正方形图的时候(以宽度为基准缩小)
                    scale = orginalWidht / 1080;
                }
                Log.i(TAG, "coundScale: " + scale);
                opeions.inSampleSize = scale;
            }
        }
    }
    /**
     * 进行图片尺寸裁剪
     *
     * @param loadBitmap 本地图片资源
     * @return 尺寸处理后的资源
     */
    private Bitmap cutFile(Bitmap loadBitmap) {
        Bitmap mCutBitmap = null;
        if (loadBitmap != null) {
            //获取经过第一次处理后图片的尺寸;
            int mLoadBitmapWidth = loadBitmap.getWidth();
            int mLoadBitmapHeight = loadBitmap.getHeight();
            float scaleX = 0;
            float scaleY = 0;
            //图片的宽高比例
            float picScale = (float) mLoadBitmapWidth / mLoadBitmapHeight;
            //计算压缩尺寸比(无论图片大小,直接规定尺寸)
            if (mLoadBitmapWidth > mLoadBitmapHeight) {
                //长图片的时候(宽度缩放到1080,高度安装原图的宽高比缩放尺寸)
                scaleX = 1080.0F / mLoadBitmapWidth;
                scaleY = 1080.0F / picScale / mLoadBitmapHeight;
            } else if (mLoadBitmapWidth < mLoadBitmapHeight) {
                //高图的时候
                scaleX = 1080.0F / mLoadBitmapWidth;
                scaleY = 1920.0F / mLoadBitmapHeight;
            } else {
                //正方形图的时候(按照宽度为基准缩放)
                scaleX = 1080.0F / mLoadBitmapWidth;
                scaleY = scaleX;
            }
            //创建一个矩阵
            Matrix mMatrix = new Matrix();
            //设置缩放比例
            mMatrix.postScale(scaleX, scaleY);
            //生成新的Bitmap
            mCutBitmap = Bitmap.createBitmap(loadBitmap, 0, 0, mLoadBitmapWidth, mLoadBitmapHeight, mMatrix, false);
        }
        return mCutBitmap;
    }

    /**
     * 质量压缩
     *
     * @param mBitmap 处理尺寸后的资源
     * @return 压缩结束后的文件
     */
    private File qualtiy(Bitmap mBitmap) {
        File mFile = null;
        if (mBitmap != null) {
            //设置压缩后图片不超过100KB
            int maxKB = 100;
            //创建一个缓存区
            ByteArrayOutputStream mByteArrayOutputStream = new ByteArrayOutputStream();
            //默认压缩质量(不压缩)
            int options = 100;
            //压缩后的大小
            int endKB = 0;
            do {
                //清空缓存区
                mByteArrayOutputStream.reset();
                //将数据写入缓存区
                mBitmap.compress(Bitmap.CompressFormat.JPEG, options, mByteArrayOutputStream);
                //降低质量
                options -= 5;
                //重新计算缓存区数据大小
                endKB = mByteArrayOutputStream.toByteArray().length;
                //如果压缩系数小于0的时候直接跳出循环
                if (options <= 0) {
                    break;
                }
                //判断当前资源大小是否大于期望大小
            } while (endKB / 1024 > maxKB);
            //创建一个输入流
            FileOutputStream mFileOutputStream = null;
            BufferedOutputStream mBufferedOutputStream = null;
            //创建一个空文件
            mFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/manageEnd.jpg");
            try {
                mFileOutputStream = new FileOutputStream(mFile);
                mBufferedOutputStream = new BufferedOutputStream(mFileOutputStream);
                //将压缩后的数据写入都空文件中
                mBufferedOutputStream.write(mByteArrayOutputStream.toByteArray());
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (mByteArrayOutputStream != null && mBufferedOutputStream != null && mFileOutputStream != null) {
                        //关闭流
                        mByteArrayOutputStream.flush();
                        mBufferedOutputStream.flush();
                        mFileOutputStream.close();
                        mBufferedOutputStream.close();
                        mByteArrayOutputStream.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return mFile;
    }

简单的压缩图片就这些,代码中基本的注释都有,如果文章中有什么不合适或者有好想法的书友可以在评论中提出,我会尽快修改!谢谢~~

注意:
记得添加文件读写权限
GitHub主页

上一篇下一篇

猜你喜欢

热点阅读