优秀的编程知识分享平台

网站首页 > 技术文章 正文

如何用代码检测png图片是否包含透明通道?

nanyue 2024-09-05 18:12:50 技术文章 3 ℃

微信的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()就能判断是否含有透明通道

Tags:

最近发表
标签列表