微信的APM工具之一ApkChecker可以对apk文件进行全方位的检测。其中的一项功能就是将apk中所有不含有透明通道的PNG图片检测出来。那么,检测不含有透明通道的PNG图片有什么用呢?用处是大大的。
首先,有的应用是需要将PNG图片转化成WebP格式的,但是android系统原生一开始对WebP的支持是不支持透明通道的,后来随着版本的演进,WebP才支持了透明通道。所以,如果没有使用Fresco图像库(因为只有Fresco图像库才对WebP支持到android 2.3版本),那么为了兼容低系统版本,只能将不支持透明通道的PNG图片转成WebP格式。
其次,有些背景复杂的图片,使用JPG格式的图片要比PNG格式的图片小很多,这种情况是可以将PNG格式转成JPG格式的,以达到缩小体积的目的。但是,JPG格式是不支持透明通道的,所以只能将这部分不支持透明通道的背景复杂的图片转成JPG格式。
以上说明了,ApkChecker提供检测不含有透明通道的PNG图片的原因。因为,我们在一定的条件下可以对这种类型的图片进行处理来进行优化。
那么,ApkChecker又是如何检测不含有透明通道的PNG图片的呢?
private void findNonAlphaPng(File file) throws IOException {
if (file != null) {
if (file.isDirectory()) {
File[] files = file.listFiles();
for (File tempFile : files) {
findNonAlphaPng(tempFile);
}
} else if (file.isFile() && file.getName().endsWith(ApkConstants.PNG_FILE_SUFFIX) && !file.getName().endsWith(ApkConstants.NINE_PNG)) {
BufferedImage bufferedImage = ImageIO.read(file);
if (bufferedImage != null && bufferedImage.getColorModel() != null && !bufferedImage.getColorModel().hasAlpha()) {
String filename = file.getAbsolutePath().substring(inputFile.getAbsolutePath().length() + 1);
if (entryNameMap.containsKey(filename)) {
filename = entryNameMap.get(filename);
}
long size = file.length();
if (entrySizeMap.containsKey(filename)) {
size = entrySizeMap.get(filename).getFirst();
}
if (size >= downLimitSize * ApkConstants.K1024) {
nonAlphaPngList.add(Pair.of(filename, file.length()));
}
}
}
}
}
1、检测是否为目录,如果是目录则递归调用
2、判断文件是否以.png结尾,而不是以.9.png结尾的
3、使用javax中的ImageIO工具得到BufferedImage对象
4、使用BufferedImage的getColorModel().hasAlpha()就能判断是否含有透明通道