Android WebP 图片压缩与传输图片压缩与传输
1. 简介简介
直到4g时代,流量依然是宝贵的东西。而移动网络传输中,最占流量的一种载体:图片,成为了我们移动开发者不得不关注的一个问题。
我们关注的问题,无非是图片体积和质量如何达到一个比较和谐的平衡,希望得到质量不错的图片同时体积还不能太大。
走在时代前列的谷歌给出了一个不错的答案——WebP。
WebP是一种图片文件格式,在相同的压缩指标下,webp的有损压缩能比jpg小 25-34%。而在我自己的测试里,有时候能小50%。
2. 大企业背书大企业背书
WebP在2010年发布第一个版本,到现在已经6年了,谷歌旗下的各种网站G+、以及非常有代表性的YouTube,他的视频文件格式WebM就是基于WebP构造的。
据说腾讯、淘宝、美团也有部分应用。
3. Android 端端 JPG 转换转换 WebP
RxJava线程转换:
String[] imgs = new String[]{"1.jpg", "2.jpg", "3.jpg", "4.jpg", "5.jpg"};
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/test/";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// test = Api.getBuilder().create(Test.class);
String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE
, Manifest.permission.READ_PHONE_STATE
, Manifest.permission.CAMERA};
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(permissions, 0);
}
compress();
}
private void compress() {
Observable.from(imgs)
.subscribeOn(Schedulers.io())
.doOnNext(new Action1<String>() {
@Override
public void call(String imgName) {
compress(imgName);
}
})
.subscribe();
}
private void compress(String imgName) {
try {
File file = new File(path, imgName);
Log.i("compress", "jpg start");
byte[] bytes = BitmapUtil.compressBitmapToBytes(file.getPath(), 600, 0, 60, Bitmap.CompressFormat.JPEG);
File jpg = new File(path, imgName + "compress.jpg");
FileUtils.writeByteArrayToFile(jpg, bytes);
Log.i("compress", "jpg finish");
Log.i("compress", "----------------------------------------------------");
Log.i("compress", "webp start");
byte[] bytes1 = BitmapUtil.compressBitmapToBytes(file.getPath(), 600, 0, 60, Bitmap.CompressFormat.WEBP);//分别是图片路径,宽度高度,质量,和图片类型,重点在这里。
File webp = new File(path, imgName + "compress.webp");
FileUtils.writeByteArrayToFile(webp, bytes1);
Log.i("compress", "webp finish");
} catch (IOException e) {
e.printStackTrace();
}
}
我的测试机器也是Oneplus 1 ,CM13,所以需要获取相应的权限。
利用RxJava来做线程操作,在io线程里做了耗时操作。
public static byte[] compressBitmapToBytes(String filePath, int reqWidth, int reqHeight, int quality, Bitmap.CompressFormat format) {
Bitmap bitmap = getSmallBitmap(filePath, reqWidth, reqHeight);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(format, quality, baos);
byte[] bytes = baos.toByteArray();
bitmap.recycle();
Log.i(TAG, "Bitmap compressed success, size: " + bytes.length);
return bytes;
}
public static Bitmap getSmallBitmap(String filePath, int reqWidth, int reqHeight) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, options);
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
options.inJustDecodeBounds = false;
// options.inPreferQualityOverSpeed = true;
return BitmapFactory.decodeFile(filePath, options);
}
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
int h = options.outHeight;
int w = options.outWidth;
int inSampleSize = 0;
if (h > reqHeight || w > reqWidth) {
float ratioW = (float) w / reqWidth;
float ratioH = (float) h / reqHeight;
inSampleSize = (int) Math.min(ratioH, ratioW);
}
inSampleSize = Math.max(1, inSampleSize);
return inSampleSize;
}
根据输入的宽高值计算分辨率的缩小比例,再根据输入的压缩质量数值,压缩图片,获得压缩后bitmap,然后再将其保存成本地文件。
这是非常常见的图片压缩手段。
4. WebP对比对比
我用我日常生活里拍下的照片来做简单的对比测试,不是特别严谨,仅供简单的参考。