首页 » 后端 » PHP » 正文

判断png图片是否含有alpha通道的透明数据

发布者:站点默认
2013/07/30 浏览数(2,490) 分类:PHP, UI 判断png图片是否含有alpha通道的透明数据已关闭评论

介绍

关于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
 * 来自:http://www.welefen.com/how-to-detect-png-has-alpha-transparent.html
 * @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;
}
点击返回顶部
  1. 留言
  2. 联系方式