java用ImageIo.read 读取webp格式图片返回null

一、问题描述

今天收到一个bug就是imageio读取图片会返回null,具体如下

image

但是其他的图片就没有问题

image

二、问题分析

结合百度发现这张图片原本的后缀并非是jpg,使用notpard++打开就可以发现

image

好家伙是webp格式的!!!!

WebP是google开发的一种旨在加快图片加载速度的图片格式。图片压缩体积大约只有JPEG的2/3,并能节省大量的服务器带宽资源和数据空间。是现代图像格式,提供了优越的无损和有损压缩的图片在网络上。使用WebP,网站管理员和web开发人员可以创建更小、更丰富的图像,使网页更快。

WebP无损的png图像小26%。WebP有损图像是25 - 34%小于等效SSIM质量指数可比JPEG图像

无损WebP支持透明(也称为alpha通道)的成本只有22%额外的字节。对有损压缩RGB压缩情况下是可以接受的,有损WebP还支持透明度,通常提供3×PNG相比较小的文件大小。

但是!!!由于Webp格式推出比较晚, Jdk 内置的图片编解码库对此并不支持。我只需要知道如何把webp格式转换成jpg或者其他格式就可以了!!!

image

三、解决问题

1、在百度找到一个api(地址如下)

我是地址 友情建议,最好用0.1.0哪个版本的其他版本试了都有问题~~~~~~

2、由于这个项目并未发布到maven中央仓库,所以需要手动导入本地jar包.

(1)、maven导包

<dependency> 
  <groupId>com.github.nintha</groupId> 
  <artifactId>webp-imageio-core</artifactId> 
  <version>{versoin}</version> 
  <scope>system</scope> 
  <systemPath>${project.basedir}/libs/webp-imageio-core-{version}.jar</systemPath> 
</dependency>

(2)、gradle导包

dependencies {
  compile fileTree(dir:'src/main/resources/libs',include:['*.jar'])
}

当然了,你想放在自己仓库中也是无可厚非的

3、上代码

(1)、Webp编码

public static void main(String args[]) throws IOException {
  String inputPngPath = "test_pic/test.png";
  String inputJpgPath = "test_pic/test.jpg";
  String outputWebpPath = "test_pic/test_.webp";

  // Obtain an image to encode from somewhere
  BufferedImage image = ImageIO.read(new File(inputJpgPath));

  // Obtain a WebP ImageWriter instance
  ImageWriter writer = ImageIO.getImageWritersByMIMEType("image/webp").next();

  // Configure encoding parameters
  WebPWriteParam writeParam = new WebPWriteParam(writer.getLocale());
  writeParam.setCompressionMode(WebPWriteParam.MODE_DEFAULT);

  // Configure the output on the ImageWriter
  writer.setOutput(new FileImageOutputStream(new File(outputWebpPath)));

  // Encode
  writer.write(null, new IIOImage(image, null, null), writeParam);
}

(2)、Webp解码

public static void main(String args[]) throws IOException {
  ImageReader reader = ImageIO.getImageReadersByMIMEType("image/webp").next();

  WebPReadParam readParam = new WebPReadParam();
  readParam.setBypassFiltering(true);

  // Configure the input on the ImageReader
  reader.setInput(new FileImageInputStream(new File(webp图片地址)));

  // Decode the image
  BufferedImage image = reader.read(0, readParam);

  ImageIO.write(image, "jpg", new File(输出jpg的地址,png什么的也可以));
}

搞完收工!


作者:迷途者寻影而行
链接:ImageIo.read 返回null - 掘金