美文网首页前端&优化程序员
搭建自己的图片处理服务 — 智能裁剪、旋转、占位一站搞定

搭建自己的图片处理服务 — 智能裁剪、旋转、占位一站搞定

作者: 记下笔记 | 来源:发表于2018-11-04 21:43 被阅读566次
    本次使用的图片素材

    前言

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

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

    因果

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

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

    还没有服务器?快领取一张高额优惠券

    效果预览

    可以实现对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 限制的服务器。
    还没有服务器?快领取一张高额优惠券

    相关文章

      网友评论

      • 谟之乐:赞,加上这段配置,再配个 https 美滋滋

        location ~ ^/api/imageproxy/ {
        # pattern match to capture the original URL to prevent URL
        # canonicalization, which would strip double slashes
        if ($request_uri ~ "/api/imageproxy/(.+)") {
        set $path $1;
        rewrite .* /$path break;
        }
        proxy_pass http://localhost:8080;
        }
        记下笔记:@谟之乐
        感谢提供 nginx 配置

        有具体的例子吗?我这边用了都挺好用的。
        谟之乐:有些图片好像并不好使啊

      本文标题:搭建自己的图片处理服务 — 智能裁剪、旋转、占位一站搞定

      本文链接:https://www.haomeiwen.com/subject/jrnrxqtx.html