本次使用的图片素材

前言

文章有点长,感觉有用的朋友可以先加收藏。
前两天刚搭建了自己的博客,并写了一篇介绍性的文章:《极简博客搭建,搭建超级简单又好看》,这几天准备写点文章体验一下这款博客。发现不论是撰写文章还是展示效果,都非常符合我的品味,真是太棒了。

直到今天我上传了一张图片,于是便有了这篇文章。

因果

一般情况,我写一篇博客会直接上传图片到文章,有时上传的尺寸并不太适合在文章内显示。就有了打开 PS 或者截取一部分再上传,这就放慢了写博文的速度。我就想有没有在线处理的方式,这样就免去了简单修图的烦恼。

网上也找到很多现成的接口,不过像我们这种都想把核心技术掌握在自己手上的人来说,这不能满足我们的欲望。而且可定制性太小,这样这个解决方案就出炉了!

没有服务器? 来参加阿里云双 11 底价团,12 号前 99.5/台起!

优惠的一小部分
查看更多

效果预览

可以实现对jpeg,png,webp(仅解码),tiff和gif图像格式(包括GIF动画)的裁剪、旋转、等操作。更多效果,可快速向下滑动,查看其它操作的效果图。

效果预览

准备

和以往的文章一样,本文章也一样尽力做到通俗易懂,使用的命令尽量简单,让更多的人可以用上好用的服务。

主要用到的工具

  1. Docker
  2. 开源库 imageproxy (不需要具体了解,没有安装配置等其它操作,写在这里只是为了让想 DIY 的朋友知道下核心功能)

启动服务

  1. 安装 Docker (已安装的忽略)
    CentOS
    Windows
    Mac
    启动服务非常简单可简单的用 Docker 命令运行此服务。
  1. 启动图片处理服务
    mkdir -p /data/image
    docker run --restart always --name image-service -p 8080:8080 -v /data/image:/image -d willnorris/imageproxy -cache /image -addr 0.0.0.0:8080
    当然你不想保存图片到本地的话,可以运行如下命令
    docker run --restart always --name image-service -p 8080:8080 -d willnorris/imageproxy -addr 0.0.0.0:8080
    参数解释(不关心的不用看,可直接看第 3 步)
    docker run: 表示运行一个容器,可以想像成运行一个程序
    --restart always:表示程序如果死掉就自动重新启动,保证一直提供服务
    --name image-service: 给你的程序起个名字,image-service 可以换成任何名字
    -v /data/image:/image: 表示把你本地的一个目录放到程序里面用,注:这个目录是容器里面图片保存的文件夹,这里这么操作是当你删除这个容器的时候,你所获取过的图片可直接提供服务,不需重新拉取图片。注意:如果是 Mac 或者 windows 启动不了,需要检查 /data/目录 docker 是否有操作的权限
    -p 8080:8080: 把容器里的一个端口映射到你的宿主机上(也就是你操作的这台服务器上,注意:请检查你的服务器安全组或者防火墙是否对这个端口开放,否则可能外部无法访问你的服务)
    willnorris/imageproxy: 镜像名
    -cache /image: (镜像内参数,也就是你个程序提供的可配置参数), 设置图片缓存在容器内的/image 文件夹内,对应你机子的 /data/image
    -addr 0.0.0.0:8080:(镜像内参数,也就是你个程序提供的可配置参数), 绑定容器内的 0.0.0.0 ip(也就是所有的 ip) 8080 端口上。对应你机子上的 8080端口,这个视你-p 参数而定。

本文章使用的测试图片地址:

http://www.picloud.me/images/2015/03/29/fcfc854b160ef5adb93006a02352b647.jpg

  1. 到这里你已经启动了你的服务,已经可以很好的达到效果了。下面演示一下如何使用:
    主要使用方式 http://localhost:8080/{options}/{remote_url}

解释

{options} - 你需要对目录图片作的调整
{remote_url} - 原图地址

示例:http://localhost:8080/800x/http://www.picloud.me/images/2015/03/29/fcfc854b160ef5adb93006a02352b647.jpg

我的效果
你可以随意修改当前的**{options}**在当前URL中就是800x,可以换成100x200x, 200x300 看看具体效果,下面我们来讲一下 {options}部分可以怎么配置,来达到智能裁剪、旋转、占位等效果。

  1. 现在你的图片处理服务已经启动了。当然图片每一次加载的时候会有点慢,因为第一次访问时需要去目标地址把图片下载到本地,而后通过你的链接提供服务。当然你加了文件缓存后,只要地址不变,你的图片将会通过本地提供服务,而不会再去远端下载。聪明的你可能已经尝试了一些参数来达到你想要的效果了,也可能知道占位功能如何实现了,那么下面我们就详细看下有哪些参数可以配置,能达到怎样华丽的效果。

参数详解

  1. 定宽,高度自适应
    {多少像素}x
    例:200x800x(上面例子就是使用了这个参数)
  1. 高度的百分之多少,宽度自适应
    x{百分比}
    例:x0.15 (高度的 15%) 、x0.8(高度的 80%)
  1. 按固定宽高裁剪图片(这个用来做点位图再好不过了,随便选张图,占位无难度)
    {宽度}x{高度}
    例:400x300 生成 400px * 300px的图片,自动裁剪
  1. 正方形图片(生成头像的时候很有用)
    {数字}
    例:96 (生成 96*96 的头像)
  1. 第二个参数
    之前说的都是只有一个参数,有时你可能需要旋转一下,或者翻转一下,传第二个参数可以达到你想要的效果。

翻转图片

600,fh 这里的参数表示生成一个 600*600 且左右翻转,如果想要水平翻转,可以使用 fv,或者两个一起使用,变成 600,fv,hv,当然你也可以和前面的 1,2,3,4 讲到的参数配合使用。
图片翻转

旋转图片

r90 逆时针旋转 90 度, 这里的度数只能是 90, 180, 270 其它的不生效。注意:图片有一个 EXIF 属性,此属性是图片内置的方向属性,当前服务使用的工具已经自动旋转成原始的方向了,相关资料可以自己查一下,关键字:图片 EXIF 属性
智能裁剪?

图片质量

q80设置图片为 80%的质量(默认质量为 95%)图片质量越小,图片的大小会更小,可以节省带宽、提高加载加载图片的速度。
图片质量测试

截取图片中的一部分

cx600,cy500,cw300,ch300,100这部分参数就很有意思了,c你可以认为是裁剪,这样x, yw, h就组成两个坐标(600,500)(300,300),表示从这张图片的(600,500)开始,截取一张 300px*300px 的图片, 后面的 100 是之前 第4 点 说到的,缩放到正方形,这样就有了如下的效果。当然这些参数也可以和之前的共用,也没有顺序的关系。
截取并生成一张 100 像素的头像

智能裁剪

sc加入此参数,可以实现智能裁剪。可以做到图片感知扩展,压缩扩展人脸不变形(人脸感知),不过这个我感觉可以优化一下,试了下效果没那么好。
image.png

服务命令启动参数

当前我们使用了-cache /image -addr 0.0.0.0:8080这两个启动参数,在参数介绍里已经介绍过了,这里我们来说明一下 -cache 这个 flag, 现在这个是直接传了文件给它,实现了把图片缓存到了本地文件。这里还可以缓存到以下地方:

缓存

  1. 缓存到内存
    -cache memory:200:4h 缓存到内存,最大内存使用为 200MB, 且最多缓存 4 小时。容量和过期时间可选,也可以不指定-cache memory,默认使用100MB内存。
  2. 缓存到亚马逊存储
    s3 URL (例:s3://region/bucket-name/optional-path-prefix)
    3.缓存到 Google 云
    gcs URL (例:gcs://bucket-name/optional-path-prefix)
  3. 缓存到微软的世纪互联
    azure URL (例: azure://container-name/)
    如果是存到世纪互联,你需要提供两个环境变量:
    AZURESTORAGE_ACCOUNT_NAME(account name)
    AZURESTORAGE_ACCESS_KEY(access key)
  4. 缓存到 Redis
    redis URL (例:redis://hostname/)
    如果 redis 有密码,需要环境变量
    REDIS_PASSWORD

服务拉取远端使用的 referrers

可以通过 -referrers example.com来设置

限制图片拉取的站

-remoteHosts example.com,example1.com设置只从example.com, example1.com获取图片,其它的源图地址将不被服务。这样可以防止别人恶意使用你的服务。

小结

到这里,你已经可以为你的博客或其它提供高定制化的图片服务了,包括裁剪、旋转等功能。这样,很多修图的工作就可以放到这个服务里去做。当然,这个服务还有很多小的问题,比如感觉裁剪扩充效果不好,估计作者也在优化。如果长期没有动作的话,我倒可以写一个类似功能的,如果有机会,可以在后期的博客中与大家见面。

还有就是缓存的地点基本是国外的服务,像国内的七牛、阿里 OSS、腾讯等云存储没有接入,这方面都有现在的库,如果自己使用可以自行接入。

有任何问题欢迎评论讨论,也可私信我。

当前服务比较耗资源,如果要布当前服务的话,不要选择有 cpu 限制的服务器。
没有服务器? 来参加阿里云双 11 底价团,12 号前 99.5/台起!