Chinaunix首页 | 论坛 | 博客
  • 博客访问: 696715
  • 博文数量: 260
  • 博客积分: 7033
  • 博客等级: 少将
  • 技术积分: 2633
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-13 23:15
文章分类

全部博文(260)

文章存档

2012年(2)

2011年(41)

2010年(78)

2009年(139)

我的朋友

分类:

2010-07-03 13:55:39

用途:
研究从PhoneView中拿出来的iPhone/iPad应用程序中的png文件。



[转]
修正iPhone里的png文件为标准格式
2010年05月03日 星期一 23:13

本想“借”用一下iphone里漂亮的天气图标,没想到在pc上无法使用。google了 一下才知道iphone里的png文件并不是标准格式,不知道什么原因,apple在png文件头之后加了一个非标准的CgBI数据段,IDAT段图像数 据也没有传统的压缩数据头和尾,并且红色和蓝色是反的。国外已经有了把iphone上的png文件转换为标准格式的, 我不太会编译,所以自己用php照猫画虎写了个转换函数。


转换后的效果:
png

使用方法:

iphone_fix_png($path);

运行后,修正后的图片会放到fixed文件夹内。

如果要修正一个目录下的所有png文件,可以这样做:

foreach (glob($path . '/*.png') as $image)
{
  
iphone_fix_png($image);
}

iphone_fix_png函数代码如下:

下载:
  1. /**
  2. * fix iPhone PNGs to PNG-compatible format
  3. *
  4. * @author: legend <legendsky@hotmail.com>
  5. * @copyright UGiA.CN
  6. * @link:
  7. *
  8. * usage:
  9. *
  10. * include('iphone_fix_png.php');
  11. *
  12. * iphone_fix_png($path);
  13. */
  14. function iphone_fix_png($file)
  15. {
  16. $png_header = "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a"; // PNG
  17. $data_chunk = "\x49\x44\x41\x54"; // IDAT
  18. $end_chunk = "\x49\x45\x4e\x44"; // IEND
  19. $cgbi_chunk = "\x43\x67\x42\x49"; // CgBI

  20. // read chunks
  21. $size = filesize($file);
  22. $fp = fopen($file, "r");
  23.   
  24. // check png header
  25. $header = fread($fp, 8);
  26. if ($header != $png_header)
  27. {
  28. trigger_error("Not a PNG file!", E_USER_ERROR);
  29. return false;
  30. }

  31. // generate output path
  32. $base = dirname($file);
  33. preg_match("/(.+?)(\.png)$/i", basename($file), $m);
  34. $filename   = $m[1];
  35. $suffix    = $m[2];

  36. if (is_dir($base . "/fixed") || false != @mkdir($base . "/fixed", 0700))
  37. {
  38. $path = $base . "/fixed/" . basename($file);
  39. }
  40. else
  41. {
  42. $path = $base . "/" . $filename . "_fixed" . $suffix;
  43. }

  44. // output stream
  45. $fd = fopen($path, "w");
  46. fwrite($fd, $png_header);

  47. $offset = 8;

  48. // do
  49. while ($offset < $size)
  50. {
  51. $length = current(unpack('N', fread($fp, 4)));
  52. $chunk = array (
  53. 'length' => pack('N', $length),
  54. 'name' => fread($fp, 4),
  55. 'data' => $length > 0 ? fread($fp, $length) : '',
  56. 'crc' => fread($fp, 4)
  57. );

  58. $offset += 4 + 4 + $length + 4;

  59. // fix IDAT chunk
  60. if ($chunk['name'] == $data_chunk)
  61. {
  62. $inflated = gzinflate($chunk['data']);
  63. $deflated = gzcompress($inflated);

  64. $chunk['data'] = $deflated;
  65. $chunk['length'] = pack('N', strlen($deflated));
  66. $chunk['crc'] = pack('N', crc32($data_chunk . $deflated));
  67. }   

  68. // drop cgbi chunk
  69. if ($chunk['name'] != $cgbi_chunk)
  70. {
  71. fwrite($fd, join("", $chunk));
  72. }
  73. }

  74. fclose($fp);
  75. fclose($fd);

  76. // flip the red/blue channels
  77. $im = imagecreatefrompng($path);
  78. imagesavealpha($im, true); // save alpha

  79. for ($i = 0; $i < imagesx($im); $i++)
  80. {
  81. for ($j = 0; $j < imagesy($im); $j++)
  82. {
  83. $rgba = imagecolorat($im, $i, $j);

  84. $a = ($rgba & 0x7F000000) >> 24;
  85. $r = ($rgba & 0xFF0000) >> 16;
  86. $g = ($rgba & 0x00FF00) >> 8;
  87. $b = ($rgba & 0x0000FF);

  88. $color = imagecolorallocatealpha($im, $b, $g, $r, $a);

  89. imagesetpixel($im, $i, $j, $color);
  90. }
  91. }

  92. imagepng($im, $path);
  93. }

参考:



阅读(1415) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~