#! https://zhuanlan.zhihu.com/p/392491580
本篇文章写作于
2021.07.23
作为一名前端工程师,我们经常会在 H5
, 或者小程序中,使用 Canvas
来处理或生成图片。
不过在某些禁用 javascript
场景下,我们往往需要在服务端预先把图片处理好,再返回给不同的客户端进行使用。
本篇文章就主要给大家介绍,如何使用腾讯云 SCF,多快好省的搭建一个图象处理函数。
看这篇文章之前,建议同学们可以初步了解一下,下方罗列的一些初级知识:
当然不了解以上技术也不影响阅读,此文章涉及的知识较为入门,用例也只是一个一个 Hello World
罢了。
如同 jsdom
可以在 nodejs
里构建 window
,document
上下文 , node-canvas
也是 canvas
在 nodejs
环境下的一套实现。
在浏览器中,我们知道 Canvas
可以做非常多的事情:
在 nodejs
中,我们同样也有生成和处理图像的需求,
往常我们会使用 imagemagick,GraphicsMagick 这种已经很成熟的方案。
不过,这些库对于我们这些前端开发来说,存在一定的学习成本。
反观 Canvas API
,大家都很熟悉,一下子把学习成本降低了。
而且使用这种方式,也可以降低兼容现有 Canvas 前端库的成本。
首先我们需要安装 node-canvas
的一个 编译 环境
如下列表格展示:
OS | Command |
---|---|
OS X | Using Homebrew:brew install pkg-config cairo pango libpng jpeg giflib librsvg |
Ubuntu | sudo apt-get install build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev |
Fedora | sudo yum install gcc-c++ cairo-devel pango-devel libjpeg-turbo-devel giflib-devel |
Solaris | pkgin install cairo pango pkg-config xproto renderproto kbproto xextproto |
OpenBSD | doas pkg_add cairo pango png jpeg giflib |
Windows | See the wiki |
Others | See the wiki |
从列表中可以看到,它依赖着许多的第三方 lib
库。而这些库,并没有被预置在官方的 SCF 镜像里。
此时就需要 自定义镜像部署 这个功能上场了,它把构建 SCF runtime
的权力,下放到我们用户手中,以此来满足更复杂的业务需求。
我们把容器环境搭建好后,配合 Web 函数 ,只需要对外暴露一个 http
监听的端口号,就可以提供服务,实在是非常方便。
首先我们需要构建本地的 开发容器环境
和 线上SCF的容器环境
这里我使用了最流行的 Alpine
Linux 发行版。
同时我们也从上述依赖表格中,也可以获得 alpine
版本需要安装的 依赖。
接下来我们就可以写出构建线上 SCF的容器环境
的 Dockerfile
:
# lts 版本的 nodejs
FROM node:14-alpine
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json yarn.lock /usr/src/app/
# alpinelinux 国内镜像地址,防止下载过慢
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
&& apk add --no-cache \
build-base \
g++ \
cairo-dev \
jpeg-dev \
pango-dev \
giflib-dev \
&& apk add --update --repository http://dl-3.alpinelinux.org/alpine/edge/testing \
libmount \
ttf-dejavu \
ttf-droid \
ttf-freefont \
ttf-liberation \
ttf-ubuntu-font-family \
fontconfig \
&& yarn --prod
COPY ./src /usr/src/app/src
EXPOSE 9000
ENTRYPOINT ["yarn" ,"start"]
上述 Dockerfile
,主要做的事情就是,准备一下运行环境,拷贝代码,下载字体和暴露一下端口和启动命令。
代码部分就不贴了,感兴趣文章末尾有源码链接
接着开始编写我们的代码了
在这里,我们生成以 2 种图像为主,image/svg+xml
和 image/png
(jpeg)
在服务端根据参数
在服务端根据参数
Canvas
,构建图像chartjs-node-canvas
chart.js
,直接生成图表的图片我们也可以在服务端去使用 echarts
, @antv/f2
来生成,本质也是类似的。
而且,我们也可以使用一些额外的数据源,来生成更有意义的图片,
比如结合 octokit
,在服务端去动态的抓取 Github
用户数据来生成内容。
原先 event 函数
接受上传文件,需要在 API 网关
那里开启 Base64
编码的选项。
而 web 函数
可以直接透传,就不需要考虑这一块(再次说明 web 场景下,开发体验好很多),
我们可以直接接收 从客户端组装的 FormData
,在服务端解析 multipart/form-data
格式,提取文件后进行处理。
比如:
这里我写了一个前端上传图片,去色的功能在我的博客站 (手机可访问)
最后再返回一下处理完成的 Canvas Buffer
, 标注一下 Content-Type
就 OK 了
像 Github
本身也可以通过 Cache-Control
这个响应头来给 camo.githubusercontent.com
设置资源的缓存。
相比普通的部署,自定义镜像部署是不需要上传代码的,所以自然不需要在 yml
文件里配置 src
这个选项
这里我节选了一段配置文件中的核心片段:
# serverless.yml
app: github-node-canvas
stage: dev
component: scf
name: github-node-canvas-scf
inputs:
name: ${name}
region: ap-shanghai
type: web
image: # 镜像配置
# registryId: tcr-xxx # 容器镜像服务名称,企业版必须
imageType: personal # 镜像类型:personal - 个人,enterprise - 企业版,public - 镜像模板
imageUrl: ${env:IMAGE_URI} # 从环境变量中取 镜像Url
events:
- apigw:
parameters:
protocols:
- http
- https
environment: release
endpoints:
- path: /
method: ANY
function:
type: web
其中最重要的就是 image
下的 imageUrl
配置项
它由url
,tag
,sha256
三部分组成,格式类似于 {url}:{tag}@{sha256}
例如 ccr.ccs.tencentyun.com/tcb-xxxxxxxx-iuit/your-project:v1.0.0@sha256:xxxxxx
sha256
用来标识镜像的一个唯一值,它可以在 :
腾讯云控制台
-> 容器服务
-> 个人镜像
-> 进入指定镜像详情中找到版本的镜像 ID (SHA256) , 如图所示:
yuga sun
大佬提供)最后我们直接执行 components deploy
就部署成功了
ps: 这里笔者直接使用的
@serverless/components
, 使用serverless
的同学,请使用serverless deploy
具体配置可以查看 sonofmagic/ascii-art-avatar 这个仓库的 serverless.yml
文件
上图中的文字,图标,二维码,Svg 动画,雷达图均为服务端生成
就这样一个简单的 使用 Web 函数
+ 自定义镜像部署
的案例 就完成了。
实际上,它能做到的功能,远远不止如此,更是大大拓宽了 Serverless
的能力。
不过在使用自定义镜像部署的实践中,笔者也发现目前部署成功的函数,冷启动时间较长,
我们往往也需要搭配,预制并发实例
这个功能进行进一步的配合。
sonofmagic/ascii-art-avatar Host by tencent cloud scf
sonofmagic/github-readme-svg Host by vercel