Web 函数自定义镜像实战:构建图象处理函数

本篇文章写作于 2021.07.23

前言

作为一名前端工程师,我们经常会在 H5, 或者小程序中,使用 Canvas 来处理或生成图片。

不过在有些禁用 javascript 场景下,我们往往需要在服务端,预先把图片处理好,再返回给不同的前端进行使用。

这篇文章,主要借用一个自定义装饰 Github markdown 文件的函数, 来给大家介绍,如何在腾讯云SCF上,多快好省的搭建一个图象处理函数。

Requirements

看这篇文章之前,建议同学们可以初步了解一下,下方罗列的一些初级知识:

  • h5 canvas & svg
  • Nodejs
  • Docker
  • Serverless Framework Components
  • Tencent SCF Web 函数 + 自定义镜像

当然不了解以上技术也不影响阅读,毕竟此文章涉及的知识比较入门,笔者写这篇文章的目的也只是给大家呈现一个 Hello World 罢了(笑~)

在服务端构建 Canvas

Why node-canvas ?

如同 jsdomnodejs 里构建 window , documentnode-canvas 也是 canvasnodejs 环境的一套实现。

在浏览器中,我们都知道 Canvas 可以做非常多的事情:

  • 简单的随便画点图形,导入几张图片处理一下
  • 复杂的图表,游戏,Webgl渲染等等。

nodejs 中,我们同样也有生成和处理图像的需求,

往常我们会使用 imagemagick,GraphicsMagick 这种业界非常成熟的方案。

不过,这些对于我们这些前端开发来说,存在一定的学习成本。

反观 Canvas API,大家都非常熟悉,一下子把学习成本降低了。

而且使用这种方式,也可以降低兼容现有Canvas前端库的成本。

How?

首先我们需要安装 node-canvas 的一个 Compiling 环境

如下列表格展示:

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镜像里。

此时就需要我们的自定义镜像功能上场了,它把构建runtime的权力,下放到我们用户手中。

我们把容器环境搭建好后,配合Web函数,只需要对外暴露一个http监听的端口号就可以,实在是非常方便。

构建 Dockerfile

首先我们需要构建本地的 开发容器环境SCF的容器环境

这里我使用了 Alpine 这个Linux 发行版, 这个懂得都懂在此不再叙述了。

同时我们也从上述依赖表格中,也可以推测获得出 alpine 版本需要安装的 依赖。

接下来我们就可以写出 SCF的容器环境Dockerfile (非生产环境):

FROM node:14-alpineRUN mkdir -p /usr/src/app
WORKDIR /usr/src/appCOPY 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 --prodCOPY ./src /usr/src/app/srcEXPOSE 9000ENTRYPOINT ["yarn" ,"start"]

上述文件,主要做的就是,准备一下运行环境,拷贝一下代码,下载一下字体,暴露一下端口和启动命令,完事。

Coding

代码部分就不贴了,有兴趣文章末尾有源码链接

图像生成

接着开始编写我们的代码了

在这里,我们生成以2种图像为主,image/svg+xmlimage/png (jpeg)

Svg

在服务端根据参数

  1. 渲染任意 antd icon 的 svg 内容
  2. 在服务端生成任意内容的 二维码
  3. 生成 svg动画 (非js)

Png

在服务端根据参数

  1. 任意调用Canvas,构建图像
  2. 安装 chartjs-node-canvas chart.js,直接生成图表的图片

我们也可以在服务端去使用 echarts 来生成,本质也是差不多的

当然由于图片是服务端生成的,我们也可以在里面加入些额外的数据源,

比如结合 @octokit 在服务端去动态的抓取 Github 用户数据来生成更加有意义的内容。

图像处理

原先 event函数 接受上传文件,需要开启 Base64 编码

web函数 直接透传,就不需要考虑这一块(再次说明web场景下,开发体验好很多),

可以直接接收 客户端组装的 FormData ,在服务端解析 multipart/form-data ,提取文件后进行处理。

比如:

  • 在前端上传一个图片,我给它打水印,去色,裁剪都是可以的
  • 又或者上传 2 个图片,我们也能进行缝合等等操作

这里我写了一个前端上传图片,去色的功能在我的博客站(手机可run)

图像去色的在线地址

最后再返回一下处理完成的 Canvas Buffer , 标注一下 Content-Type 就 OK 了

要客户端缓存的话,就设置个 Cache-Control

Github 本身也可以通过 Cache-Control 这个响应头来给 camo.githubusercontent.com 设置资源的缓存,所以它还是非常必要的。

部署

相比普通的部署,自定义镜像它是不需要上传代码的 , 所以自然不需要 配置 src 这个选项

这里我节选了一段比较核心的配置文件:

app: github-node-canvas
stage: dev
component: scf
name: github-node-canvas-scf
inputs:name: ${name}region: ap-shanghaitype: webimage: # 镜像配置# registryId: tcr-xxx # 容器镜像服务名称,企业版必须imageType: personal # 镜像类型:personal - 个人,enterprise - 企业版,public - 镜像模板imageUrl: ${env:IMAGE_URI} # 镜像Urlevents:- apigw:parameters:protocols:- http- httpsenvironment: releaseendpoints:- path: /method: ANYfunction:type: web

其中值得一说的就是这个image 下的 imageUrl

它的格式 format 似于 {url}:{tag}@{sha256}

例如 ccr.ccs.tencentyun.com/tcb-xxxxxxxx-iuit/your-project:v1.0.0@sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

其中 sha256 是必须的,用来标识镜像的一个唯一值。

sha256 可以在 :

  1. docker push 之后,在命令行显示出来,进行复制:
  2. 或者 push 成功后,进入腾讯云控制台 -> 容器服务 -> 个人镜像 -> 进入指定镜像详情中找到版本的镜像 ID(SHA256) , 如图所示:

ps: sha256 太长会被 antd table 组件压成 tooltip, 建议直接 Ctrl + Shift + I 来进行 CV

最后我们直接执行 components deploy 就部署成功了

ps: 这里笔者直接使用的 @serverless/components , 使用 serverless 的同学,请使用 serverless deploy

具体可以查看 sonofmagic/ascii-art-avatar 这个仓库的 serverless.yml 配置

展现效果

Github public profile

上图中的一些文字,Icon,二维码,Svg 动画,雷达图均为服务端生成

Image grayscale

后记

就这样一个简单的 使用 Web 函数 + 自定义镜像的实战就介绍完了

实际上它能做的远远不止如此,可以做出非常复杂的效果,来赋予不同的意义。

不过在使用自定义镜像的实践中,笔者也发现目前也存在冷启动时间过长的问题,

我们往往也需要搭配 , 预制并发实例 这个功能一起使用这个功能

Live Demos

图像去色的在线地址

作者的 Github public profile

Repositories

sonofmagic/ascii-art-avatar Host by tencent cloud scf

sonofmagic/github-readme-svg Host by vercel

Web 函数自定义镜像实战:构建图象处理函数相关推荐

  1. 指针数组概念 和 函数指针数组实战 和指针函数的概念和实战

    1.指针数组概念 int (*p)[4]; 是一个数组指针 ,强调的是指针,这是指针指向的是某个数组 (*p)这个指针含有四个元素的一维数组 指针数组呢? 强调的是数组 我们可以定义一个数组,数组里面 ...

  2. lambda函数 java_使用 Java 构建 Lambda 函数 - AWS Lambda

    本文属于机器翻译版本.若本译文内容与英语原文存在差异,则一律以英文原文为准. 使用 Java 构建 Lambda 函数 您可以在 AWS Lambda 中运行 Java 代码.Lambda 为运行代码 ...

  3. oracle path函数,自定义类似 sys_connect_by_path 功能的函数

    真是简单又巧妙的办法!美中不足的是他只设置了一组全局变量,如果调用多次就会发生覆盖,比如: SELECT hierarchy.sys_connect_by_path(level, firstname, ...

  4. 利用Packer自定义镜像创建容器集群

    阿里云容器服务Kubernetes集群支持CentOS操作系统,在绝大多数情况下可以满足客户的要求.但是有些客户由于业务系统对操作系统依赖比较高,希望定制化一些操作系统参数,则可以用自定义镜像来创建K ...

  5. sklearn基于make_scorer函数为Logistic模型构建自定义损失函数并可视化误差图(lambda selection)和系数图(trace plot)+代码实战

    sklearn基于make_scorer函数为Logistic模型构建自定义损失函数并可视化误差图(lambda selection)和系数图(trace plot)+代码实战 # 自定义损失函数 i ...

  6. sklearn基于make_scorer函数为Logistic模型构建自定义损失函数+代码实战(二元交叉熵损失 binary cross-entropy loss)

    sklearn基于make_scorer函数为Logistic模型构建自定义损失函数+代码实战(二元交叉熵损失 binary cross-entropy loss) # 广义线性模型中的各种连接函数: ...

  7. R语言dplyr包arrage函数排序dataframe实战:单列排序、多列排序、自定义排序

    R语言dplyr包arrage函数排序dataframe实战:单列排序.多列排序.自定义排序 目录 R语言dplyr包arrage函数排序dataframe实战:单列排序.多列排序

  8. php打印函数console,PHP内置Web Server探究(2)自定义PHP控制台输出console函数

    PHP内置Web Server探究(二)自定义PHP控制台输出console函数 我们在开发APP的服务器端,当和APP进行联调时通常需要实时跟踪URL请求和参数的接收情况. 但PHP并没有像Pyth ...

  9. 函数计算镜像加速:从分钟到秒的跨越

    简介:函数计算 FC 正式发布容器镜像加速,通过按需读取和更高效的解压技术在不同场景下加速 50%-80%,即使 GB 级别的镜像也可以在几秒内完成端到端启动. 作者信息: Shuai Chang,阿 ...

最新文章

  1. 那些有趣的Webview细节
  2. python 写cs程序_Python cs.cmdutils包_程序模块 - PyPI - Python中文网
  3. Log Buffer
  4. 组合筛选vue_Vue 3 组合式API介绍
  5. inner join 和 exists 效率_19条效率至少提高3倍的MySQL技巧
  6. latex正文显示运算符
  7. cross-entropy函数
  8. php mysqli result,PHP mysqli_free_result()与mysqli_fetch_array()函数详解
  9. OpenStack基金会 ( OSF)演进为开源基础设施基金会
  10. [笔记] 最大权闭合子图最大流最小割相关笔记
  11. Android修行手册-TextView常用属性篇
  12. Latex: 添加IEEE会议论文作者信息
  13. React移动web极致优化
  14. html清除图层,ps按delete不能删除图层怎么办?
  15. (Python+OpenCV)图像平移
  16. 《实用python程序设计》练习题:向量点积计算
  17. 2020年陕西省高等职业院校技能大赛信息安全管理与评估赛项竞赛手册
  18. FileChannel阅读笔记
  19. 编译android版本protobuf
  20. python里的self

热门文章

  1. StringUtils的使用
  2. NLP中文分词工具比较
  3. 【压缩感知合集3】压缩感知的背景与意义
  4. 云管平台 | 云成本分析优化管理
  5. js对象转数组可枚举属性和不可枚举属性
  6. Linux加密和安全篇(一)gpg、对称和非对称加密、哈希算法
  7. 机器人导航——路径跟踪
  8. 2022年最新目标跟踪顶会论文及模型整理分享
  9. XML里的<![CDATA[<=]]>是什么意思?
  10. N-最短路径分词算法