图片有三种存在形式:硬盘上时是file,网络传输时是stream,内存中是stream或bitmap,所谓的质量压缩,它其实只能实现对 file的影响,你可以把一个file转成bitmap再转成file,或者直接将一个bitmap转成file时,这个最终的file是被压缩过的,但 是中间的bitmap并没有被压缩(或者说几乎没有被压缩,我不确定),因为bigmap在内存中的大小是按像素计算的,也就是width * height,对于质量压缩,并不会改变图片的像素,所以就算质量被压缩了,但是bitmap在内存的占有率还是没变小,但你做成file时,它确实变小 了;
而尺寸压缩由于是减小了图片的像素,所以它直接对bitmap产生了影响,当然最终的file也是相对的变小了;
B. Android图片压缩-大小与质量压缩以及图片保存
一、前言:
2.质量压缩
注意:
第二次压缩之前都要先清空 baos.reset(); 再进行压缩 image.compress(Bitmap.CompressFormat.JPEG, quality, baos);
有时候我们采用质量压缩没有效果,有可能是每次压缩的质量过小,所以我们可以尝试修改压缩质量(quality)是10;
quality压缩机提示,0-100。0表示压缩
小尺寸,100意味着最大质量的压缩。一些
格式,如无损的PNG,将忽略质量设定;
3.混合方式压缩
链接: https://www.jianshu.com/p/12835d5ebc72
C. 说说在 Android 中如何压缩图片
1:ByteArrayOutputStream 压缩图片质量,不会改变图片大小
java">privateBitmapcompressImage(Bitmapimage){
ByteArrayOutputStreambaos=newByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG,100,baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
intoptions=100;while(baos.toByteArray().length/1024>100){//循环判断如果压缩后图片是否大于100kb,大于继续压缩
baos.reset();//重置baos即清空baos
image.compress(Bitmap.CompressFormat.JPEG,options,baos);//这里压缩options%,把压缩后的数据存放到baos中
options-=10;//每次都减少10}
ByteArrayInputStreamisBm=newByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
Bitmapbitmap=BitmapFactory.decodeStream(isBm,null,null);//把ByteArrayInputStream数据生成图片
returnbitmap;
}
2:就是改变图片大小
privateBitmapgetimage(StringsrcPath){
BitmapFactory.OptionsnewOpts=newBitmapFactory.Options();//开始读入图片,此时把options.inJustDecodeBounds设回true了
newOpts.inJustDecodeBounds=true;
Bitmapbitmap=BitmapFactory.decodeFile(srcPath,newOpts);//此时返回bm为空
newOpts.inJustDecodeBounds=false;intw=newOpts.outWidth;inth=newOpts.outHeight;//现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
floathh=800f;//这里设置高度为800f
floatww=480f;//这里设置宽度为480f//缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
intbe=1;//be=1表示不缩放
if(w>h&&w>ww){//如果宽度大的话根据宽度固定大小缩放
be=(int)(newOpts.outWidth/ww);
}elseif(w<h&&h>hh){//如果高度高的话根据宽度固定大小缩放
be=(int)(newOpts.outHeight/hh);
}if(be<=0)
be=1;
newOpts.inSampleSize=be;//设置缩放比例//重新读入图片,注意此时已经把options.inJustDecodeBounds设回false了
bitmap=BitmapFactory.decodeFile(srcPath,newOpts);returncompressImage(bitmap);//压缩好比例大小后再进行质量压缩}
D. android图片压缩避免OOM
简单吹下牛:很多app都会要加载图片,但是如果不压缩图片就很容易OOM,
个人看来OOM 出现原因总的来说分为两种:
一种是内存溢出(好像在扯淡,OOM本身就是内存溢出)
另一种是:图片过大,一个屏幕显示不完全造成,似乎也是一。。 如有错误纯属扯淡;
为了避免上面的情况:加载图片的时候可以进行压缩,上传的时候要可以进行压缩,在图片不可见的时候进行回收(onDetach()),再吹一句 用了fresco+压缩之后加载图片完全没问题了。
一、质量压缩方法:
privateBitmap compressImage(Bitmap image) {
ByteArrayOutputStream baos =newByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG,100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
intoptions =100;
while( baos.toByteArray().length /1024>100) {//循环判断如果压缩后图片是否大于100kb,大于继续压缩
baos.reset();//重置baos即清空baos
image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中
options -=10;//每次都减少10
}
ByteArrayInputStream isBm =newByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
Bitmap bitmap = BitmapFactory.decodeStream(isBm,null,null);//把ByteArrayInputStream数据生成图片
returnbitmap;
}
二、图片按比例大小压缩方法(根据Bitmap图片压缩)
privateBitmap comp(Bitmap image) {
ByteArrayOutputStream baos =newByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG,100, baos);
if( baos.toByteArray().length /1024>1024) {//判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出
baos.reset();//重置baos即清空baos
image.compress(Bitmap.CompressFormat.JPEG,50, baos);//这里压缩50%,把压缩后的数据存放到baos中
}
ByteArrayInputStream isBm =newByteArrayInputStream(baos.toByteArray());
BitmapFactory.Options newOpts =newBitmapFactory.Options();
//开始读入图片,此时把options.inJustDecodeBounds 设回true了
newOpts.inJustDecodeBounds =true;
Bitmap bitmap = BitmapFactory.decodeStream(isBm,null, newOpts);
newOpts.inJustDecodeBounds =false;
intw = newOpts.outWidth;
inth = newOpts.outHeight;
//现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
floathh = 800f;//这里设置高度为800f
floatww = 480f;//这里设置宽度为480f
//缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
intbe =1;//be=1表示不缩放
if(w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放
be = (int) (newOpts.outWidth / ww);
}elseif(w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放
be = (int) (newOpts.outHeight / hh);
}
if(be <=0)
be =1;
newOpts.inSampleSize = be;//设置缩放比例
//重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
isBm =newByteArrayInputStream(baos.toByteArray());
bitmap = BitmapFactory.decodeStream(isBm,null, newOpts);
returncompressImage(bitmap);//压缩好比例大小后再进行质量压缩
}