如何判断png图片是否含有alpha通道的透明

7044次阅读  |  发布于5年以前

介绍

关于png的乱七八糟的一些东西这里就不说了。在前端的日常开发中,我们经常要用到png图片。

由于IE6默认是不支持图片含有alpha透明的,这时候一般就要用到一些hack方式了。常用的方式有:

1、CSS里添加filter(手工添加很麻烦)

2、用gif来代替(有瑕疵)

3、使用vml(JS来实现,并且动态操作DOM时可能也要调用)

对于使用filter的方式,有没有自动化的方式呢?

如果使用程序来自动添加_filter和_background的话,就要做到如何去识别当前引用的图片是否含有alpha的透明。

png图片数据结构

查资料得知,png是如下的数据结构:

(1) PNG文件署名域

8字节的PNG文件署名域用来识别该文件是不是PNG文件。该域的值是: 十进制数 137 80 78 71 13 10 26 10 十六进制数 89 50 4e 47 0d 0a 1a 0a

(2) 数据块的结构

数据块里包含了文件头数据块IHDR(header chunk),它包含有PNG文件中存储的图像数据的基本信息,并要作为第一个数据块出现在PNG数据流中,而且一个PNG数据流中只能有一个文件头数据块。

Width 4 bytes 图像宽度,以像素为单位 Height 4 bytes 图像高度,以像素为单位 Bit depth 1 byte 图像深度: 索引彩色图像:1,2,4或8 灰度图像:1,2,4,8或16 真彩色图像:8或16 ColorType 1 byte 颜色类型: 0:灰度图像,1,2,4,8或16 2:真彩色图像,8或16 3:索引彩色图像,1,2,4或8 4:带α通道数据的灰度图像,8或16 6:带α通道数据的真彩色图像,8或16 Compression method 1 byte 压缩方法(LZ77派生算法) Filter method 1 byte 滤波器方法 Interlace method 1 byte

知道了png图片的数据格式,我们就可以通过depth和colorType来判断图片是否含有alpha通道的透明。

具体实现

/**
     * 
     * 判断一个图片是否是包含alpha通道的png
     * @param string $file
     */
    function is_alpha_png($file) {
        if (! file_exists ( $file )) {
            return false;
        }
        $f = @fopen ( $file, 'r' );
        if (! $f) {
            return false;
        }
        $bin = fread ( $f, 29 );
        fclose ( $f );
        $info = @unpack ( "C8c/C8char/C4width/C4height/Cdepth/Ccolortype", $bin );
        $png = array (
            137, 
            80, 
            78, 
            71, 
            13, 
            10, 
            26, 
            10 
        );
        //判断头是否是png文件
        for($i = 0; $i < 8; $i ++) {
            if ($png [$i] != $info ['c' . ($i + 1)]) {
                return false;
            }
        }
        list ( $width, $height ) = getimagesize ( $file );
        //这里用width3和4就可以了
        $w = $info ['width3'] * 256 + $info ['width4'];
        $h = $info ['height3'] * 256 + $info ['height4'];
        //判断当前获取跟系统获取的值是否相同
        if ($width != $w || $height != $h) {
            return false;
        }
        $depth = $info ['depth'];
        $colorType = $info ['colortype'];
        if ($depth == 8 || $depth == 16) {
            if ($colorType == 6) {
                return true;
            }
        }
        return false;
    }

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8