Android Picasso加载webp格式图片节省流量(2)

boolean isWebPFile = Utils.isWebPFile(stream);//判断是不是webp格式的图片文件,webp格式使用BitmapFactory与Jpg,png不同
    markStream.reset(mark);
    // When decode WebP network stream, BitmapFactory throw JNI Exception and make app crash.
    // Decode byte array instead
    if (isWebPFile) {
      byte[] bytes = Utils.toByteArray(stream);//将输入流读取成字节数组,此处会不会OOM呢?
      if (calculateSize) {
        BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
        RequestHandler.calculateInSampleSize(request.targetWidth, request.targetHeight, options,//根据imageView的大小计算应该读取的bitmap大小
            request);
      }
      return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);//webp格式的图片要使用decodeByteArray方法,否则会crash
    } else {
      //...省略jpg和png的转换代码
      return bitmap;
    }
  }这里有个很重要的方法是Utils.isWebPFile(),那么这个方法是怎么根据一个输入流判断是jpg还是webp格式的文件呢,肯定不能用扩展名吧,于是点进去看下


private static final int WEBP_FILE_HEADER_SIZE = 12;
private static final String WEBP_FILE_HEADER_RIFF = "RIFF";
private static final String WEBP_FILE_HEADER_WEBP = "WEBP";

static boolean isWebPFile(InputStream stream) throws IOException {
    byte[] fileHeaderBytes = new byte[WEBP_FILE_HEADER_SIZE];
    boolean isWebPFile = false;
    if (stream.read(fileHeaderBytes, 0, WEBP_FILE_HEADER_SIZE) == WEBP_FILE_HEADER_SIZE) {
      // If a file's header starts with RIFF and end with WEBP, the file is a WebP file
      isWebPFile = WEBP_FILE_HEADER_RIFF.equals(new String(fileHeaderBytes, 0, 4, "US-ASCII"))
          && WEBP_FILE_HEADER_WEBP.equals(new String(fileHeaderBytes, 8, 4, "US-ASCII"));
    }
    return isWebPFile;
  }
实现原理也不麻烦,用的linux常用的判断文件类型的方法,就是读取一个文件的头几个字节,然后转换成ASCII字符看看是啥文件,这样正好也利用了inputStream读取的顺序,很简单的完成了jpg,png和webp文件的识别。

注意:不要在这个方法执行之前对inputStream执行读取操作,否则很有可能无法判断webp文件

如果你的webp文件加载不出来,不要忘了测试这个方法的返回值。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/be1ed3849c06e68b19f18da73b6c2de8.html