[php]修正iPhone里的png文件为标准格式
本想“借”用一下iphone里漂亮的天气图标,没想到在pc上无法使用。google了一下才知道iphone里的png文件并不是标准格式,不知道什么原因,apple在png文件头之后加了一个非标准的CgBI数据段,IDAT段图像数据也没有传统的压缩数据头和尾,并且红色和蓝色是反的。国外已经有了把iphone上的png文件转换为标准格式的代码,我不太会编译,所以自己用php照猫画虎写了个转换函数。
转换后的效果:
使用方法:
iphone_fix_png($path);
运行后,修正后的图片会放到fixed文件夹内。
如果要修正一个目录下的所有png文件,可以这样做:
foreach (glob($path . '/*.png') as $image)
{
iphone_fix_png($image);
}
{
iphone_fix_png($image);
}
iphone_fix_png函数代码如下:
- /**
- * fix iPhone PNGs to PNG-compatible format
- *
- * @author: legend <legendsky@hotmail.com>
- * @copyright UGiA.CN
- * @link: http://www.ugia.cn/?p=134
- *
- * usage:
- *
- * include('iphone_fix_png.php');
- *
- * iphone_fix_png($path);
- */
- function iphone_fix_png($file)
- {
- $png_header = "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a"; // PNG
- $data_chunk = "\x49\x44\x41\x54"; // IDAT
- $end_chunk = "\x49\x45\x4e\x44"; // IEND
- $cgbi_chunk = "\x43\x67\x42\x49"; // CgBI
- // read chunks
- $size = filesize($file);
- $fp = fopen($file, "r");
- // check png header
- $header = fread($fp, 8);
- if ($header != $png_header)
- {
- trigger_error("Not a PNG file!", E_USER_ERROR);
- return false;
- }
- // generate output path
- $base = dirname($file);
- preg_match("/(.+?)(\.png)$/i", basename($file), $m);
- $filename = $m[1];
- $suffix = $m[2];
- if (is_dir($base . "/fixed") || false != @mkdir($base . "/fixed", 0700))
- {
- $path = $base . "/fixed/" . basename($file);
- }
- else
- {
- $path = $base . "/" . $filename . "_fixed" . $suffix;
- }
- // output stream
- $fd = fopen($path, "w");
- fwrite($fd, $png_header);
- $offset = 8;
- // do
- while ($offset < $size)
- {
- $length = current(unpack('N', fread($fp, 4)));
- $chunk = array (
- 'length' => pack('N', $length),
- 'name' => fread($fp, 4),
- 'data' => $length > 0 ? fread($fp, $length) : '',
- 'crc' => fread($fp, 4)
- );
- $offset += 4 + 4 + $length + 4;
- // fix IDAT chunk
- if ($chunk['name'] == $data_chunk)
- {
- $inflated = gzinflate($chunk['data']);
- $deflated = gzcompress($inflated);
- $chunk['data'] = $deflated;
- $chunk['length'] = pack('N', strlen($deflated));
- $chunk['crc'] = pack('N', crc32($data_chunk . $deflated));
- }
- // drop cgbi chunk
- if ($chunk['name'] != $cgbi_chunk)
- {
- fwrite($fd, join("", $chunk));
- }
- }
- fclose($fp);
- fclose($fd);
- // flip the red/blue channels
- $im = imagecreatefrompng($path);
- imagesavealpha($im, true); // save alpha
- for ($i = 0; $i < imagesx($im); $i++)
- {
- for ($j = 0; $j < imagesy($im); $j++)
- {
- $rgba = imagecolorat($im, $i, $j);
- $a = ($rgba & 0x7F000000) >> 24;
- $r = ($rgba & 0xFF0000) >> 16;
- $g = ($rgba & 0x00FF00) >> 8;
- $b = ($rgba & 0x0000FF);
- $color = imagecolorallocatealpha($im, $b, $g, $r, $a);
- imagesetpixel($im, $i, $j, $color);
- }
- }
- imagepng($im, $path);
- }
参考:
The iPhone Dev Wiki: PNG Images
iPhone PNG fixer-upper
The iPhone Dev Wiki: Apple Embedded Images
PNG文件结构分析
Hick said,
December 31, 2007 @ 3:18 pm
突然发现,小伙的 logo 很有水准!嘿嘿
kiddd said,
February 1, 2008 @ 12:39 pm
文章不错,留记号
test said,
August 4, 2011 @ 2:41 pm
娃哈哈
bigmonstercai said,
February 18, 2012 @ 3:43 pm
没接触过php语言,不知道怎么运行这个脚本啊?直接在cmd中输入iphone_fix_png($path)吗?
bigmonstercai said,
August 15, 2013 @ 11:44 am
测试过了,没用,还是只能还原一半。
崔允局匠 said,
December 8, 2013 @ 11:13 am
杭州最好的夜场是杭州东方魅力www.dongfangmeili.cn
杭州最好的ktv是哪儿?是杭州东方魅力www.dongfangmeili.cn
杭州夜场招聘首选杭州东方魅力www.dongfangmeili.com.cn
杭州最好的夜总会是杭州东方魅力www.dongfangmeili.com.cn
杭州东方魅力官方网站欢迎你 联系电话:13666653761 官方微信:dongfangmeili
杭州最好的ktv是www.dongfangmeili.cn
杭州夜场招聘杭州夜场招聘www.dongfangmeili.cn