PHP处理高分辨率图片的问题

今天小伙伴在群里问了这么一个问题:php

出现这种状况就是由于内存不足,PHP程序直接退出了,报错大概以下:前端

报错

上图的意思就是说,咱们能使用的内存最大是8M,可是处理这个图片还须要额外的41bytes,就会致使内存不足,这是一个很严重的错误。在对图片进行操做前须要将图片的全部信息读入内存中,同时还会使用另外一部份内存同于处理计算并缓存输出,因此内存大小的使用仍是和图片的大小有关。 git

PHP中图片的处理都是使用了GD库,这个库提供了不少方法让PHP能够更方便地对图片进行操做,支持的图片格式以下:github

回到一开始的问题,那个小伙伴须要处理高分辨的图片,图片大小必然很大,因此就会出现内存不够的状况,解决方法仍是有不少的。后端

1. 设置图片最大可上传的大小

前端上传前能够先检测下大小,若是超过最大值直接就不请求接口,同时为安全起见,后端接收到请求后也要检测大小,防止程序异常退出。缓存

2. 压缩图片

3. 关闭memory_limit

群里的小伙伴最后使用了一种简单粗暴的方式解决了该问题,直接在PHP中关闭memory_limit安全

set_time_limit(0);
@ini_set('memory_limit','-1');

这样虽然解决了问题,但不优雅也不安全,一样在php.ini配置文件中将memory_limit的值设置很大也能解决:学习

memory_limit = 256M

PHP代码中也能够这样设置:测试

ini_set('memory_limit', '256M');

上面咱们将memory_limit参数固定了,这就带来一个弊端,由于大多数状况下不须要这么大的内存,有点浪费资源,最好的作法就是根据须要来设置memory_limit,我写了一个以下方法可供参考:spa

public function setMemoryLimit($filename){
    // 控制执行时间
    set_time_limit(50);

    $maxMemoryUsage = 256M;
    $width = 0;
    $height = 0;
    $size = ini_get('memory_limit');

    // 获取图片大小
    list($width, $height) = getimagesize($filename);

    // 计算须要的内存,并转换成'M'单位
    // 4 由于png图片一个像素有4字节
    // 1.5 是一个调整因子,由于memory_limit不是那么精确
    // 详细能够查看: http://php.net/imagecreatefromjpeg#76968
    $size = $size + floor(($width * $height * 4 * 1.5 + 1048576) / 1048576);

    if ($size > $maxMemoryUsage){
        $size = $maxMemoryUsage;
   }

   // 更新
   ini_set('memory_limit',$size.'M');
}

最后说一下,网上说GD库是比较耗内存的,但我这里没有作过测试。Github上有个C的项目叫libvips/libvips

libvips/libvips

libvips/libvips readme

能够在不占用不少内存的状况下提升图片处理的速度,这是地址:https://github.com/libvips/li...,有时间能够学习下。

相关文章
相关标签/搜索