intervention/image 中的一个小坑及其破解之法

事实上 intervention/iamge 用了很有些时日了,它的 api 设计得很简洁,文档也很全面,用起来相当顺手。

不过最近无意间发现了一个小坑。因为需要合成带微信头像的二维码,我使用 Image::make($avatarUrl) (这里的 $avatarUrl 是微信头像的链接)来产生头像,然后合成到二维码图像中去(还包括一些其它操作,比如使用模板背景、写入文字)。

写完之后一运行,发现相当慢,平均耗时 23 秒左右。起初以为是因为合成过程中进行的操作比较多、尺寸比较大,本来就应该是这个速度。不过后来闲下来,开始试着优化,即使不能提升速度,至少也搞清楚到底是什么原因这么耗时。

这一通折腾下来,发现真相竟然与合成操作的多少、尺寸没有多大关系。而关键在于我创建头像数据的姿势。

为了说明这个问题,特意写了下面的代码进行对比。

// 记录开始时间
$startTimestamp = microtime(true);

$url = 'http://wx.qlogo.cn/mmopen/XxT9TiaJ1ibf06TNRCMjQADS4opDHvQLguLZHpqkRlvuJYZicvJW4iaOalPsKIs0kpZ3F6864ZzibyObYiaucUQSrdp4pFTNDyIpxw/0';

$avatar = \Image::make($url);

// 记录结束时间
$endTimestamp = microtime(true);

info($startTimestamp);
info($endTimestamp);
info($endTimestamp - $startTimestamp);

file

上面这段代码使用 Image::make($url) 的形式,直接从 url 生成头像。从记录的日志数据来看,耗时基本上在 16 秒左右。

后来,想到了一个新姿势,其实也就是在尝试优化的过程中折腾时想到的。见下面代码:

$startTimestamp = microtime(true);

$client = new \GuzzleHttp\Client();

$url = 'http://wx.qlogo.cn/mmopen/XxT9TiaJ1ibf06TNRCMjQADS4opDHvQLguLZHpqkRlvuJYZicvJW4iaOalPsKIs0kpZ3F6864ZzibyObYiaucUQSrdp4pFTNDyIpxw/0';

$avatarResponse = $client->get($url);

$avatar = \Image::make($avatarResponse->getBody()->getContents());

$endTimestamp = microtime(true);

info($startTimestamp);
info($endTimestamp);
info($endTimestamp - $startTimestamp);

在这里我先使用 GuzzleHttp 获取头像,再使用 Image::make($data) 创建头像。

注意,要高潮了…… :sunglasses:

看看下面的日志截图,三次平均耗时在 0.07 秒左右,和前面的 16 秒相比,差了 200 多倍。
file

至于为什么会出现这种现象,自己也没搞清楚,但这无疑是一点比较有用且小众的经验。

本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 5年前 自动加精
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 16

没注意过,一直是 guzzle 下载后再 make ,因为要设置超时、文件流、授权等参数。

make($url) 是用 file_get_contents 下载的,这个是基于文件系统的,如果非常慢,可以查查是不是哪里配置有问题,比如开了 xdebug 什么的..

guzzle 是基于 curl 的,只要牵扯下载用 guzzle 或 curl 准没错...

如果你有兴趣,可以在别的机子上测试下。
再比较下 Image::make( Guzzle::get(...) )Image::make( file_get_contents(...) ) 的区别。

6年前 评论

@ElfSundae 也看过里面的源码,没有进一步尝试。

6年前 评论

关注,也同样遇到过这个问题,然后我用队列解决的.. 治标不治本

6年前 评论

确实是快了很多
我也在做类似的功能,楼主是否可以分享一下这段代码作为参考?

6年前 评论

@皓文 文中提到的项目是公司商业项目,不便直接分享其代码。不过有兴趣可以加我 QQ 412039588 讨论,兴许能帮到你。

6年前 评论

http://image.intervention.io/api/text
楼主你好,在设置文字属性时,回调里的$font->size(100) 怎么都不生效,请问有遇到这种问题吗

6年前 评论

@触不可及2016 字号只有在指明了字体文件时才会起作用的,不然会被忽略,记得这一点官文档里写了的,自己去找找。

6年前 评论
susucool

兄弟牛逼啊,没有你这一个月前的踩坑文章,不知道我要踩多久的坑,大写的赞!!!

6年前 评论

我的项目用法跟楼主一致,但是获取的速度还是在 2 - 6 秒之间,很郁闷
但在获取其他网站图片的时间,速度处于 0.2 秒左右,所以不得不问候腾讯

5年前 评论

@ZhiYuan :smile: 而且微信开发方面的限制是越来越多了。

5年前 评论

我也遇到了这个问题,我把 http 改为 https 访问就好了。

4年前 评论

@DangerHJW 写这个已经是两年多前的了,忘了当时是否用过这个办法。记得当时微信消息接口才刚开始支持443端口,而其它文件资源的链接对于 https 应用还没有像现在这样全面。

4年前 评论

有没有支持表情的字体

2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!