作为一名前端工程师,我们经常会在 H5
, 或者小程序中,使用 Canvas
来处理或生成图片。不过在某些禁用 javascript
场景下,我们往往需要在服务端预先把图片处理好,再返回给不同的客户端进行使用。
本篇文章就主要给大家介绍,如何使用腾讯云 SCF,多快好省的搭建一个图象处理函数。
使用到的技术:
看这篇文章之前,建议同学们可以初步了解一下,下方罗列的一些初级知识:
当然不了解以上技术也不影响阅读,此文章涉及的知识较为入门,用例也只是一个一个 Hello World
罢了。
jsdom
可以在 nodejs
里构建 window
,document
上下文,node-canvas
也是 canvas
在 nodejs
环境下的一套实现。在浏览器中,我们知道 Canvas
可以做非常多的事情:
在 nodejs
中,我们同样也有生成和处理图像的需求,往常我们会使用 imagemagick,GraphicsMagick 这种已经很成熟的方案。不过,这些库对于我们这些前端开发来说,存在一定的学习成本。反观 Canvas API
,大家都很熟悉,一下子把学习成本降低了。而且使用这种方式,也可以降低兼容现有 Canvas 前端库的成本。
2. 准备编译环境
首先我们需要安装 node-canvas
的一个 编译 环境,如下列表格展示:
从列表中可以看到,它依赖着许多的第三方 lib
库。而这些库,并没有被预置在官方的 SCF 镜像里。此时就需要 自定义部署 这个功能上场了,它把构建 SCF runtime
的权力,下放到我们用户手中,以此来满足更复杂的业务需求。我们把容器环境搭建好后,配合 Web 函数 ,只需要对外暴露一个 http
监听的端口号,就可以提供服务,实在是非常方便。
3. 构建 Dockerfile
首先我们需要构建本地的 开发容器环境
和 线上 SCF 的容器环境
,这里我使用了最流行的 Alpine
Linux 发行版。同时我们也从上述依赖表格中,也可以获得 alpine
版本需要安装的依赖。接下来我们就可以写出构建线上 SCF 的容器环境
的 Dockerfile
:
# lts 版本的 nodejsFROM node:14-alpine
RUN mkdir -p /usr/src/appWORKDIR /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
,主要做的事情就是,准备一下运行环境,拷贝代码,下载字体和暴露一下端口和启动命令。
4. Coding
代码部分就不贴了,感兴趣文章末尾有源码链接。
接着开始编写我们的代码了,在这里,我们生成以 2 种图像为主,image/svg+xml
和 image/png
(jpeg)。
1. Svg
在服务端根据参数:
1. 渲染 antd icon 的 svg 内容;
2. 在服务端生成任意内容的二维码;
3. 生成 svg 动画 (无 js);
2. Png
在服务端根据参数:
1. 调用 Canvas
,构建图像;
2. 使用 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.ymlapp: github-node-canvasstage: devcomponent: scfname: github-node-canvas-scfinputs: 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
用来标识镜像的一个唯一值,它可以在:
1. docker push 之后,在命令行显示出来,进行复制:
2. 或者 push 成功后,进入腾讯云控制台
-> 容器服务
-> 个人镜像
-> 进入指定镜像详情中找到版本的镜像 ID(SHA256) ,如图所示:
3. docker inspect 指令获取 (感谢yuga sun
大佬提供)
最后我们直接执行 components deploy
就部署成功了
ps: 这里笔者直接使用的
@serverless/components
,使用serverless
的同学,请使用serverless deploy
。
具体配置可以查看 sonofmagic/ascii-art-avatar 这个仓库的 serverless.yml
文件。
1. Github public profile
上图中的文字,图标,二维码,Svg 动画,雷达图均为服务端生成。
2. Image grayscale
06.
后记
就这样一个简单的 使用 Web 函数
+ 自定义镜像部署
的案例 就完成了。实际上,它能做到的功能,远远不止如此,更是大大拓宽了 Serverless
的能力。不过在使用自定义镜像部署的实践中,笔者也发现目前部署成功的函数,冷启动时间较长,我们往往也需要搭配 , 预制并发实例
这个功能进行进一步的配合,听说腾讯云 Serverless 团队正在推进镜像加速来降低冷启动时长,期待这个尽快发布上线,到时候可以一起体验看看。
Live Demos
Repositories
tencent cloud scf
vercel
本文分享自 ServerlessCloudNative 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!