最近鄙厂的图片系统在做优化,关于处理显示图片用什么程序处理有点争论,某个人是觉得imagick方便也挺好用的,不过一位同事指出用GD可能能更节省资源和提高效率,经过简单的测试,发现结果确实如此。
也罢,学习嘛,就是不断的折腾。于是就配合着一起改了一版GD的处理;这几天才发现这货功能倒是还能满足就是全过程式的调用,一般只提供了最基本的方法,很多imagick
里用到的功能需要自己封装。
例如以下2个常用的imagick
的功能
- cropImage
- resizeImage
在实现crop的时候GD里可以用imagecopyresampled
函数,它用来把一张图片采样后复制到另外一个资源里。看到这个函数的文档时,某整个人都shuffle!了,10个必填参数,还有8个是位置、尺寸相关的数字,而且文档里的说明几乎可以说是没有,看了一下后面用户贡献的示例没有太多帮助,某就只能自己折腾了。
首先需要说明的是,某这里以crop裁剪一张图片作为出发点。这个过程可以理解成这样
将图片A上截图一部分(取名叫C?),复制到新的图片画布B上,保存!
接下来,包流水账的事情某就不做了,用某的理解来看一下参数的含义。
- 先是
dst_image
和src_image
,用脚趾头想都知道这里指的就是上面说的图片B和A了,当然是GD资源。 dst_x
和dst_y
,代表了截取部分C在新画布B上的落点src_x
和src_y
,代表了截取部分C在原图片A上的位置dst_w
和dst_h
,代表了截取部分贴到新画布上的大小,注意这个可以比新画布大哦!src_w
和src_h
,代表了截取部分C的高宽,很好理解
相信大家都注意到了,这个参数的顺序很…独特?嘛,这个先不吐槽了。
先来看一个例子,原图如下,你们随意吐槽。。
例如,我想把这张图片正中的400x300的区域裁剪出来,大概算一下能得到这样一些数值
截取部分距离原图左侧有1600 / 2 - 400 / 2 => 600
,同理距离上部是1200 / 2 - 300 / 2 => 450
,那么就得到src_x
和src_y
分别是600和450。
因为,某想裁剪好的图片就是400x300,即截取部分完全填满新画布B,那么dst_x
和dst_y
就是(0, 0),这个也很容易理解;同理,因为是”复制”,所以我们可以任意调整截取部分在新画布B上的位置,这里的位置是以截取部分左上角(topleft,northwest)为基准的。
截取的大小反应在src_w
和src_h
上,这个也非常好理解,即从src_x
和src_y
出发,高度与宽度,这里是(400, 300)。
最后参数是dst_w
和dst_h
了,这个理解起来稍微有点绕,相当于复制到画布B上后的尺寸,也就是可以任意调整截取部分的尺寸,相当于一个resize。如果只是想复制到新画布的化,保留原大小即可。在这里即为(400, 300)。
最后我们就得到了所有参数,类似
$src = imagecreatefromjpeg('saya.jpg');
$dst = imagecreatetruecolor(400, 300); // 创建画布,截取大小和新图一致
imagecopyresampled($dst, $src, 0, 0, 600, 450, 400, 300, 400, 300);
最后输出就可以看到结果了www
再给一个例子,如果截取的大小超过了画布B,贴上去的时候又按照截取大小的话,超出画布B的部分的话,自然就被截掉了,如果不够大小就填不满了。
// 把原图1200x900开始的400x300大小截取后,缩放成800x300贴到一张800x600的画布上去,所以画布下半部分是空的
imagecopyresampled($dst, $src, 0, 0, 1200, 900, 800, 300, 400, 300);
↓
最后是今天整理的一段等价于imagick里cropImage的代码,欢迎各位巨巨触手凌辱。
{% gist 2866219 %}
以上
__END__