介绍
关于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; }