Android将webp格式图片转换为png格式方法

时间:2022-11-11 21:06:42
    最近项目优化的时候发现app上选择的部分图片上传到服务器后无法显示或者直接上传失败,经过跟踪发现问题出现在webp图片格式上,说到webp格式的图片,这是google自己发明的一种图片格式,在网络上使用可以比jpg和png更小,图像的清晰度还不损失,是个很好的图片格式。无奈,目前除了google的产品,android和chorme等支持外,其他地方支持的都不太如人意。有两个可以解决该问题的方法,一种是在服务器端,图片上传后,通过php转码为jpg或者png再使用;一种是在安卓端选择了webp格式的图片,本地转换为jpg或者png再上传。

    服务器转码需要php5.4版本以上,但是公司的核心系统偏偏跑在php5.4以下,而且升级php很不现实,核心系统的稳定是第一位的,所以该方法被pass掉了,接下来就该我们苦逼的android程序员揪头发了,先是在百度和google上各种搜索,基本没发现可用的解决方法,不过也提供了一点线索,有些大牛用ndk的方式解决了,仔细阅读这些文章,找到了解决路径,使用libwebp库,将webp格式图片转成bitmap,bitmap再转png或者jpg就无压力了,这就是解决办法了,不扯淡,上代码:

    准备工作:在csdn上找libwebp.so 放在armeabi 和armeabi-v7a各一份,将libwebp.jar放在依赖库里;

    核心代码,从webp到bitmap转换;

 static {
System.loadLibrary("webp");
}

private byte[] loadFileAsByteArray(String filePath) {
File file = new File(filePath);
byte[] data = new byte[(int)file.length()];
try {
FileInputStream inputStream;
inputStream = new FileInputStream(file);
inputStream.read(data);
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
return data;
}

private Bitmap webpToBitmap(byte[] encoded) {
int[] width = new int[] { 0 };
int[] height = new int[] { 0 };
byte[] decoded = libwebp.WebPDecodeARGB(encoded,encoded.length,width,height);
//byte[] decoded = libwebp.WebPDecodeARGB(encoded, encoded.length, width, height);
int[] pixels = new int[decoded.length / 4];
ByteBuffer.wrap(decoded).asIntBuffer().get(pixels);
return Bitmap.createBitmap(pixels, width[0], height[0], Bitmap.Config.ARGB_8888);
}
    图片格式判断代码:

 BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(file.getAbsolutePath(), options);
String type = options.outMimeType;
Util.printLog("image type -> ", type);
if(type.equals("image/webp")){
   Bitmap转png代码:

 Bitmap bp = webpToBitmap(loadFileAsByteArray(file.getAbsolutePath()));

String c = file.getParent();
newFile = new File(c + File.separator + System.currentTimeMillis() + ".png");
Util.printLog("webp test",file.getAbsolutePath());//
Util.printLog("webp test",newFile.getAbsolutePath());//
if(newFile.exists()){
newFile.delete();
}
FileOutputStream out;
try{
out = new FileOutputStream(newFile);
if(bp.compress(Bitmap.CompressFormat.PNG, 90, out))
{
out.flush();
out.close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}

注意事项:webp格式图片如果经过剪裁的话,虽然扩展名是.webp,但是实际格式一般是png或者jpg,请使用上面的图片格式判断代码判断实际图片格式后,再决定是否需要转换。libwebp.so 和libwebp.jar我会在我的资源里传一份 http://download.csdn.net/detail/dsb2008dsb/9813264 ,其他人共享的也有。