在总结压缩之前,先了解下,安卓中常见的三种图片格式:PEPG,PNG,JPG
JPEG
JPEG(发音为jay-peg, IPA:[ˈdʒeɪpɛg])是一种针对照片视频而广泛使用的一种压缩标准方法。这个名称代表Joint Photographic Experts Group(联合图像专家小组)。
常用的.jpg文件是有损压缩
不支持背景透明
适用于照片等色彩丰富的大图压缩
不适用于logo,线图
GIF
GIF,图像互换格式(GIF,Graphics Interchange Format)是一种位图图形文件格式,以8位色(即256种颜色)重现真彩色的图像。它采用无损压缩技术,只要图像不多于256色,则可既减少文件的大小,又保持成像的质量。
优秀的压缩算法使其在一定程度上保证图像质量的同时将体积变得很小。
可插入多帧,从而实现动画效果。
可设置透明色。
由于采用了8位压缩,最多只能处理256种颜色,故不宜应用于真彩色图片。
PNG
PNG,便携式网络图形(Portable Network Graphics,PNG)是一种无损压缩的位图图形格式,支持索引、灰度、RGB三种颜色方案以及Alpha通道等特性。
支持256色调色板技术以产生小体积文件
最高支持48位真彩色图像以及16位灰度图像。
支持Alpha通道的透明/半透明特性。
支持图像亮度的Gamma校准信息。
支持存储附加文本信息,以保留图像名称、作者、版权、创作时间、注释等信息。
使用无损压缩。
渐近显示和流式读写,适合在网络传输中快速显示预览效果后再展示全貌。
使用CRC防止文件出错。
最新的PNG标准允许在一个文件内存储多幅图像。
Android开发中的切图素材多为.png格式。
BPM
BMP(全称Bitmap)是Windows操作系统中的标准图像文件格式,可以分成两类:设备相关位图(DDB)和设备无关位图(DIB),使用非常广。它采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BMP文件所占用的空间很大。
BMP文件的图像深度可选lbit、4bit、8bit及24bit。BMP文件存储数据时,图像的扫描方式是按从左到右、从下到上的顺序。
WebP
WebP(发音weppy),是一种同时提供了有损压缩与无损压缩的图片文件格式,派生自视频编码格式VP8,是由Google在购买On2 Technologies后发展出来,以BSD授权条款发布。
从官网介绍来看,无损的WebP图片比PNG小26%,有损的WebP图片比JPEG小25-34%,同时,无损WebP支持透明及alpha通道,有损在一定条件下同样支持。
WebP 的优势体现在它具有更优的图像数据压缩算法,能带来更小的图片体积,而且拥有肉眼识别无差异的图像质量;同时具备了无损和有损的压缩模式、Alpha 透明以及动画的特性,在 JPEG 和 PNG 上的转化效果都非常优秀、稳定和统一。
参考自:javascript:void(0)
1.质量压缩法:
我发现,在质量压缩时,后面几乎压缩的很少了,这是一个5M的照片如图:
从100%,90%一直到10%,压缩量一次是:3766K–558–203–105–54–42–30–24–20–14,这个就像弹簧一样,越往后压缩越难压缩,压缩10%,和1%相差不大.但是,5M的图片压缩到200K是,图片质量明显下降.
代码:
``` public void compress(File file){
Log.i("TAG", file.getPath());
Bitmap bitmap = BitmapFactory.decodeFile(file.getPath());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int pos= 100;
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压
while(baos.size()/1024>200) {
Log.i("TAG", baos.size()/1000+"k=============="+pos);
pos -=10;
baos.reset();
bitmap.compress(Bitmap.CompressFormat.JPEG, pos, baos);
}
try {
FileOutputStream fos = new FileOutputStream(Environment.getExternalStorageDirectory().getAbsolutePath()+"/SHMedia/Photos/1234.jpg");
baos.writeTo(fos);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
2:比例压缩法:
比例压缩法至于两点
1: opts.inJustDecodeBounds = true;// 将该参数设置为 true 则加载器不加载图片, 而是把图片的 out(宽和高)的字段信息取出来
设置完,压缩比例后
opts.inJustDecodeBounds = false;//使用缩放比例进行缩放加载图片,加载器返回图片
2:opts.inSampleSize = 8;设置比例,1-3:是一样的结果,2的1次方;
4-7:压缩结果一样,2的2次方
8-15:压缩结果一样,2的三次方
16-31:压缩结果一样,2的4次方
结论:不足2的整数次方,按整数次方的前一个次方算
实验数据:
原图:2.56M
1-3: 1.42M 压缩倍数:1.66
4-7: 385k 压缩倍数:6.13
8-15:107k 压缩倍数:22
有意思的是:
本来16-31:应该是一样的结果,可是结果出乎意料:
16-24: 33K
24-31:16K
完全不按照套路出牌:在包括16以后的这个段,图片已经严重失真,已经没有意义.
public void compress1(File file){
BitmapFactory.Options opts = new BitmapFactory.Options();
// 设置为ture只获取图片大小
opts.inJustDecodeBounds = true;
opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
// 获取到屏幕对象
Display display = getWindowManager().getDefaultDisplay();
// 获取到屏幕的真是宽和高
int screenWidth = display.getWidth();
int screenHeight = display.getHeight();
// 计算缩放比例
int widthScale = opts.outWidth /screenWidth;
int heightScale = opts.outHeight /screenHeight;
int samPle = Math.max(widthScale,heightScale);
opts.inSampleSize = 2;
opts.inJustDecodeBounds = false;
Bitmap bitmap = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getAbsolutePath()+"/SHMedia/Photos/123.jpg", opts);
try {
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/SHMedia/Photos/123.jpeg")));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
有不足之处:欢迎指正