2.1 - 普通 - 未处理
今天,一朋友跟我说他在上传大png图片时,生成缩略图有问题,如果是小png图片或是其它格式的图片却是正常的,顿觉很奇怪,于是下班后在家里试了下,确实程序会报错:

提示代码199行 有错
如是就根据提示 定位到了 199行 $srcImg = $createFun($image);
$createFun是'imagecreatefrompng',
上述代码 也就是 $srcImg =imagecreatefrompng($image);时 出现了错误
报错 的大致意思是(查了下google翻译)说是:在分配19k的内存时 ,8M的内存 已经用完了 ,好奇怪
难道是imagecreatefrompng()函数的问题 ,
如是立马写了下 测试程序 demo.php
header('Content-Type:image/png');
$url="images/cover.png";
$img=imagecreatefrompng($url);
imagepng($img);
imagedestroy($img);
意思是从images目录下 加载 cover.png图片 然后 在浏览器中输出,
结果出现错误,说是图像本身有错,无法显示

然后 我有试了张png小图 ,
结果显示正常 ,

那原因 就很明显了,就是png加载大的png图片时会出现错误,并不是thinkphp框架的问题(本测试用的是thinkphp2.1版本)
如是就在百度上 搜imagecreatefrompng加载 大图出错
imagecreatefrompng() 在失败时返回一个空字符串,并且输出一条错误信息,不幸地在浏览器中显示为断链接。
说是 加载失败会返回空 但是为何失败
却没有说
继续往下看 好像解释了为何加载出错的原因 ,但是一大推英文 又看不懂
大致意思好像是说 :
imagecreatefrompng在加载大png图片是 会变态 的消耗内存,
结果也不知道是哪位朋友还提供了问题的 解决方案
The approach I used to solve the problem is:
1-The following value works for me:
$required_memory = Round($width * $height * $size['bits']);
2-Use somthing like:
$new_limit=memory_get_usage() + $required_memory;
ini_set("memory_limit", $new_limit);
4-ini_restore ("memory_limit");
php.ini 默认的内存 是8M
加载png图片时 需要的 内存 是 Round($width * $height * $size['bits']);
我计算了下加载cover.png 时需要的内存 :4900*3600*8=141120000,
141M尼玛这么大 难怪 会 加载不了呢
照着这个方法 试了下 果然 解决了问题,
在thinkphp框架的 Image.class.php代码$srcImg = $createFun($image);的前面 加上
//考虑png大图内存不足的问题
$imgArr=getimagesize($image);
$required_memory = $imgArr[0] * $imgArr[1] * $imgArr['bits'];
$new_limit=memory_get_usage() + $required_memory+200000000;
ini_set("memory_limit", $new_limit);
让程序根据加载图片的大小,自动设置需要的内存,结束之后
在thumb函数的结尾 在设置为默认的8M
ini_restore ("memory_limit")
至此,问题解决,也算是Thinkphp框架的一个小bug
