博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android-压缩大图到容量超小的图片
阅读量:6148 次
发布时间:2019-06-21

本文共 5364 字,大约阅读时间需要 17 分钟。

  • 压缩图片的宽高
/**     * 计算图片的压缩比     *     * @param options     * @param reqWidth     * @param reqHeight     * @return     */    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {        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;    }复制代码

调用calculateInSampleSize计算压缩比。并解码原图为Bitmap:

/**     * @param imagePath     * @param displayWidth     * @param displayHeight     * @return     */    private Bitmap compress(String imagePath, int displayWidth, int displayHeight) {        BitmapFactory.Options options = new BitmapFactory.Options();        options.inJustDecodeBounds = true;//只测量image 不加载到内存。        BitmapFactory.decodeFile(imagePath, options);//测量image        options.inPreferredConfig = Bitmap.Config.RGB_565;//设置565编码格式,省内存,        options.inSampleSize = calculateInSampleSize(options, displayWidth, displayHeight);        options.inJustDecodeBounds = false;        Bitmap bitmap = BitmapFactory.decodeFile(imagePath, options);//按照Options配置去加载图片到内存        return bitmap;    }复制代码

这里比较重要的inJustDecodeBounds字段,当inJustDecodeBounds为true时,调用BitmapFactory.decode时并没有把图片加载到内存中去,只是去测量图片的宽高,不不占用内存,当inSampleSize为false时,调用BitmapFactory.decoe时就把图片加载到内存去了,所有获取bitmap应在inJustDecodeBounds为false后的BitmapFactory.decode去获取。

  • 设置编码格式 android中默认格式是ARG8888,我们解码图片一般用ARG565节省图片加载到内存的大小。
ALPHA_8 代表8位Alpha位图 ARGB_4444 代表16位ARGB位图 ARGB_8888 代表32位ARGB位图 RGB_565 代表8位RGB位图 复制代码

位图位数越高代表其可以存储的颜色信息越多,当然图像也就越逼真

  • 图片质量压缩
ByteArrayOutputStream out = new ByteArrayOutputStream();//字节流输出bitmap.compress(Bitmap.CompressFormat.JPEG,50,out);//压缩成jpeg格式复制代码

compress中第一个参数是输出文件的格式,在Bitmap枚举类CompressFormat中定义,有JPEG,PNG PNG,WEBP,一般选择JPEG,压缩出来的容量小,WEBP很耗时, 耗时时间比较:WEBP>PNG>JPEG, 压缩大小:PNG>WEBP>JPEG. 第二个参数是压缩的质量比例,也就是压缩像素的显示色彩,当100时表示不压缩。当为50时表示压缩50%的质量。设置这个参数可以有效的极大的缩小图片的大小,可以按照自己的需求进行设置, 但建议一般不要大于60.第三个参数就是想要写入的图片数据的字节流数组了。

  • 字节流写出文件

我们经过上述步骤后,就拿到了字节流数据了,此时我们可以根据项目需求直接上传字节流或者保存为本地图片再上传。

ByteArrayOutputStream out = new ByteArrayOutputStream();//字节流输出        bitmap.compress(Bitmap.CompressFormat.JPEG, 50, out);//压缩成jpeg格式  压缩像素质量为50%        String fileName = imagePath.substring(imagePath.lastIndexOf("/") + 1, imagePath.lastIndexOf("."));//获取文件名        File outFile = new File("/storage/emulated/0/photoPickTemp", fileName + "_temp.jpeg");//创建压缩后的image文件        try {            if (!outFile.exists()) {//判断文件是否存在                if (outFile.createNewFile()) {//判断创建新文件是否成功                    FileOutputStream fos = new FileOutputStream(outFile);                    byte[] bytes = out.toByteArray();//字节数组                    int count = bytes.length;                    fos.write(bytes, 0, count);                    fos.close();//关闭流                    out.close();                }            }        } catch (Exception e) {            e.printStackTrace();        }复制代码
  • 获取当前屏幕宽高

工具类

  • 封装
public class ImageUtil {    public ImageUtil(){    }    public static File compressImage(String imagePath,int displayWidth,int displayHeight){        BitmapFactory.Options options=new BitmapFactory.Options();        options.inJustDecodeBounds=true;//只测量image 不加载到内存        BitmapFactory.decodeFile(imagePath,options);//测量image        options.inPreferredConfig= Bitmap.Config.RGB_565;//设置565编码格式 省内存        options.inSampleSize=calculateInSampleSize(options,displayWidth,displayHeight);//获取压缩比 根据当前屏幕宽高去压缩图片        options.inJustDecodeBounds=false;        Bitmap bitmap=BitmapFactory.decodeFile(imagePath,options);//按照Options配置去加载图片到内存        ByteArrayOutputStream out=new ByteArrayOutputStream();//字节流输出        bitmap.compress(Bitmap.CompressFormat.JPEG,50,out);//压缩成JPEG格式 压缩像素质量为50%        String fileName=imagePath.substring(imagePath.lastIndexOf("/")+1,imagePath.lastIndexOf("."));//获取文件名称        File outFile=new File("/storage/emulated/0/PhotoPickTemp",fileName+"_temp.jpeg");//创建压缩后的image文件        try {            if(!outFile.exists()){//判断新文件是否存在                if(outFile.createNewFile()){//判断创建新文件是否成功                    FileOutputStream fos=new FileOutputStream(outFile);//创建一个文件输出流                    byte[] bytes=out.toByteArray();//字节数组                    int count=bytes.length;//字节数组的长度                    fos.write(bytes,0,count);//写到文件中                    fos.close();//关闭流                    out.close();                }            }        } catch (IOException e) {            e.printStackTrace();        }        return outFile;    }    public static int calculateInSampleSize(BitmapFactory.Options options,int reqWidth,int reqHeight){//计算图片的压缩比        final int height=options.outHeight;//图片的高度        final int width=options.outWidth;//图片的宽度 单位1px 即像素点        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;    }}复制代码

转载地址:http://thmya.baihongyu.com/

你可能感兴趣的文章
ICCV2017 论文浏览记录
查看>>
科技巨头的交通争夺战
查看>>
当中兴安卓手机遇上农行音频通用K宝 -- 卡在“正在通讯”,一直加载中
查看>>
Shell基础之-正则表达式
查看>>
JavaScript异步之Generator、async、await
查看>>
讲讲吸顶效果与react-sticky
查看>>
c++面向对象的一些问题1 0
查看>>
直播视频流技术名词
查看>>
IOC —— AOP
查看>>
比特币现金将出新招,推动比特币现金使用
查看>>
数据库的这些性能优化,你做了吗?
查看>>
MS SQLSERVER通用存储过程分页
查看>>
60.使用Azure AI 自定义视觉服务实现物品识别Demo
查看>>
Oracle 冷备份
查看>>
jq漂亮实用的select,select选中后,显示对应内容
查看>>
C 函数sscanf()的用法
查看>>
python模块之hashlib: md5和sha算法
查看>>
解决ros建***能登录不能访问内网远程桌面的问题
查看>>
售前工程师的成长---一个老员工的经验之谈
查看>>
Get到的优秀博客网址
查看>>