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


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

    出现这种情况就是因为内存不足,PHP程序直接退出了,报错大概如下:

    报错

    上图的意思就是说,我们能使用的内存最大是8M,但是处理这个图片还需要额外的41bytes,就会导致内存不足,这是一个很严重的错误。在对图片进行操作前需要将图片的所有信息读入内存中,同时还会使用另一部分内存同于处理计算并缓存输出,所以内存大小的使用还是和图片的大小有关。

    PHP中图片的处理都是使用了GD库,这个库提供了很多方法让PHP可以更方便地对图片进行操作,支持的图片格式如下:

    回到一开始的问题,那个小伙伴需要处理高分辨的图片,图片大小必然很大,所以就会出现内存不够的情况,解决方法还是有很多的。

    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,我写了一个如下方法可供参考:

    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/libvips,有时间可以学习下。

    正义的程序猿

  • 相关阅读:
    WCF 通讯标准绑定
    FTP FtpWebRequest 异步上传文件
    适用于zTree 、EasyUI tree、EasyUI treegrid
    PropertyInfo 类
    通过类库ChineseChar实现将汉字转化为拼音
    使用内存流导出Excel
    钉钉开发文档示例
    .Net Mail SMTP 发送网络邮件
    C# 解析 Json数据
    Newtonsoft.Json高级用法(转)
  • 原文地址:https://www.cnblogs.com/bilberry/p/10610840.html
Copyright © 2020-2023  润新知