Android性能优化之图片压缩处理
相关概念:
* 图片压缩种类*
1 质量压缩
改变图片的呈现质量,降低清晰度
2 尺寸压缩
改变图片的尺寸达到压缩的目的
* 色位深度*
ALPHA_8: 只含透明值的 8位存储
RGB_565: 不保存透明值,其中红色通道为5位,绿色通道为6位,蓝色通道为5位
ARGB_4444:ARGB四个通道都会保存 每个通道占用4位
ARGB_8888:ARGB四个通道都会保存 每个通道占用8位 (质量最高 也是android默认的图片呈现方式)
Android图片的编码是由Skia库来完成的
Android 相机拍照得到的图片格式是 jpg格式 jpg格式 是没有透明度的通道的
所以那个上传压缩的 是通过降低 质量百分比压缩的
而对于别的 图 可以通过转为 jpg格式 将 透明度通道 去除 并且进行质量上的压缩 可以大大减少存储占用
而 png是一种无损压缩格式, 压缩大概是用行程编码算法 可以有透明效果 适合 矢量图 几何图
矢量图:矢量图形最大的优点是无论放大、缩小或旋转等不会失真 并且 是通过 公式对点、线计算得到图形 体积比位图占用小一些
jpeg比较适合存储色彩“杂乱”的拍摄图片,png比较适合存储方几何特征比较强的矢量图
相关使用
获取图片占用内存
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Log.e("原图像大小", String.valueOf(bitmap.getAllocationByteCount()));
}
被复用 Bitmap真实占用的内存大小 注意这里是内存 而不是磁盘占用
质量压缩
通过bitmap的compress()方法进行图像的质量压缩
compress(CompressFormat format, int quality, OutputStream stream)
CompressFormat format:压缩格式,它有JPEG、PNG、WEBP三种选择
int quality:0~100可选,数值越大,质量越高,图像内存越大
OutputStream stream:压缩后图像的输出流
注意!!!通过compress方法执行的是压缩磁盘占用的空间,而不是bitmap的内存占用,内存占用依旧不会变小
bitmap压缩转bitmap
// bitmap压缩转bitmap
public static Bitmap comPressBitMap(final Bitmap bitmap, final int quality){
final ByteArrayOutputStream baostream = new ByteArrayOutputStream();
// 1.压缩格式,它有JPEG、PNG、WEBP三种选择 2. 0~100可选,数值越大,质量越高 3. 压缩后图像的输出流 即压缩返回到这里
bitmap.compress(Bitmap.CompressFormat.JPEG, quality,baostream);
Bitmap newBitmap = BitmapFactory.decodeStream(new ByteArrayInputStream(baostream.toByteArray()), null, null);
try {
// 若原图不需要 则回收
bitmap.recycle();
baostream.flush();
baostream.close();
} catch (IOException e) {
e.printStackTrace();
}
return newBitmap;
}
bitmap压缩转file
// bitmap压缩转file
public static File comPressBitMap2(final Bitmap bitmap,String filePath, final int quality){
File file=new File(filePath); //将要保存图片的路径
try {
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, bos);
bos.flush();
bos.close();
// 若原图不需要 则回收
bitmap.recycle();
} catch (IOException e) {
e.printStackTrace();
}
return file;
}
Bitmap与Uri之间的转换
// 将Uri转bitmap 去压缩
Bitmap sourceBitmap = MediaStore.Images.Media.getBitmap(WaiQinActivity.this.getContentResolver(), imageUri);
// bitmap转uri
imageUri = Uri.parse(MediaStore.Images.Media.insertImage(getContentResolver(), compressedBitmap, null,null));
bitmap与file的相互转换
bitmap->File
// bitmap->File 类似压缩方法 只是将压缩比设置为100(不压缩) 通过输入输出流转换
public static File bitmapToFile(Bitmap bitmap, String filepath){
File file=new File(filepath);//将要保存图片的路径
try {
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
bos.flush();
bos.close();
// 若原图不需要 则回收
bitmap.recycle();
} catch (IOException e) {
e.printStackTrace();
}
return file;
}
File->bitmap
通过下方的filePath方式
bitmap与path的相互转换
path->bitmap
// path->bitmap
bitMBitmap = decodeFile(filePath);
尺寸压缩:
Bitmap bitmap=BitmapFactory.decodeFile(filePath,getBitmapOption(2)); //将图片的长和宽缩小味原来的1/2
private Options getBitmapOption(int inSampleSize){
System.gc();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPurgeable = true;
options.inSampleSize = inSampleSize;
return options;
}
参考:
https://juejin.im/entry/583bc1d0a22b9d006a8a7a72
https://juejin.im/post/5a1bd6595188254cc067981f