问题:项目加载webp图片不显示
背景:后台的图片从png转为了webp,出现部分图片不能显示。
原因:项目使用的glide 3.7 不支持带透明效果的webp格式图片
对策:
1.使用最新的glide 4.7.1。由于相比 glide 3.7 API改动太大,需要修改很多文件,比较麻烦。
2.修改glide 3.7 源码:按照4.7.1的代码,增加webp支持,重新打包。
以下是修改方法:
文件:com\bumptech\glide\load\resource\bitmap\ImageHeaderParser.java
加入枚举值WEBP 和WEBPA ,gettype() 方法加入webp解析 相关字段
public enum ImageType {
/** GIF type. */
GIF(true),
/** JPG type. */
JPEG(false),
/** PNG type with alpha. */
PNG_A(true),
/** PNG type without alpha. */
PNG(false),
/** WebP type with alpha. */
WEBP_A(true),
/** WebP type without alpha. */
WEBP(false),
/** Unrecognized type. */
UNKNOWN(false);
private final boolean hasAlpha;
ImageType(boolean hasAlpha) {
this.hasAlpha = hasAlpha;
}
public boolean hasAlpha() {
return hasAlpha;
}
}
//copy from glide 4.7.1
// WebP-related
// "RIFF"
private static final int RIFF_HEADER = 0x52494646;
// "WEBP"
private static final int WEBP_HEADER = 0x57454250;
// "VP8" null.
private static final int VP8_HEADER = 0x56503800;
private static final int VP8_HEADER_MASK = 0xFFFFFF00;
private static final int VP8_HEADER_TYPE_MASK = 0x000000FF;
// 'X'
private static final int VP8_HEADER_TYPE_EXTENDED = 0x00000058;
// 'L'
private static final int VP8_HEADER_TYPE_LOSSLESS = 0x0000004C;
private static final int WEBP_EXTENDED_ALPHA_FLAG = 1 << 4;
private static final int WEBP_LOSSLESS_ALPHA_FLAG = 1 << 3;
public ImageType getType() throws IOException {
final int firstTwoBytes = streamReader.getUInt16();
// JPEG.
if (firstTwoBytes == EXIF_MAGIC_NUMBER) {
return JPEG;
}
final int firstFourBytes = (firstTwoBytes << 16 & 0xFFFF0000) | (streamReader.getUInt16() & 0xFFFF);
// PNG.
if (firstFourBytes == PNG_HEADER) {
// See: http://stackoverflow.com/questions/2057923/how-to-check-a-png-for-grayscale-alpha
// -color-type
streamReader.skip(25 - 4);
int alpha = streamReader.getByte();
// A RGB indexed PNG can also have transparency. Better safe than sorry!
return alpha >= 3 ? PNG_A : PNG;
}
// GIF from first 3 bytes.
if (firstFourBytes >> 8 == GIF_HEADER) {
return GIF;
}
// WebP (reads up to 21 bytes). See https://developers.google.com/speed/webp/docs/riff_container
// for details.
if (firstFourBytes != RIFF_HEADER) {
return UNKNOWN;
}
// Bytes 4 - 7 contain length information. Skip these.
streamReader.skip(4);
final int thirdFourBytes =
(streamReader.getUInt16() << 16 & 0xFFFF0000) | (streamReader.getUInt16() & 0xFFFF);
if (thirdFourBytes != WEBP_HEADER) {
return UNKNOWN;
}
final int fourthFourBytes =
(streamReader.getUInt16() << 16 & 0xFFFF0000) | (streamReader.getUInt16() & 0xFFFF);
if ((fourthFourBytes & VP8_HEADER_MASK) != VP8_HEADER) {
return UNKNOWN;
}
if ((fourthFourBytes & VP8_HEADER_TYPE_MASK) == VP8_HEADER_TYPE_EXTENDED) {
// Skip some more length bytes and check for transparency/alpha flag.
streamReader.skip(4);
return (streamReader.getByte() & WEBP_EXTENDED_ALPHA_FLAG) != 0 ? ImageType.WEBP_A : ImageType.WEBP;
}
if ((fourthFourBytes & VP8_HEADER_TYPE_MASK) == VP8_HEADER_TYPE_LOSSLESS) {
// See chromium.googlesource.com/webm/libwebp/+/master/doc/webp-lossless-bitstream-spec.txt
// for more info.
streamReader.skip(4);
return (streamReader.getByte() & WEBP_LOSSLESS_ALPHA_FLAG) != 0 ? ImageType.WEBP_A : ImageType.WEBP;
}
return ImageType.WEBP;
}
文件:com\bumptech\glide\load\resource\bitmap\Downsampler.java
TYPES_THAT_USE_POOL 集合内加入WEBP 和WEBPA
private static final Set<ImageHeaderParser.ImageType> TYPES_THAT_USE_POOL = EnumSet.of(
ImageHeaderParser.ImageType.JPEG, ImageHeaderParser.ImageType.PNG_A, ImageHeaderParser.ImageType.PNG, ImageHeaderParser.ImageType.WEBP, ImageHeaderParser.ImageType.WEBP_A);
重新打包文件下载:https://download.youkuaiyun.com/download/u011809807/10498207