斗图不用怕!用 serverless 随时创建你的表情包

2023-11-21 16:10

本文主要是介绍斗图不用怕!用 serverless 随时创建你的表情包,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

meme economy(表情包经济)显然是下一件大事!这是互联网注意力经济的自然延伸,Elon Musk也沉迷于此。据估计,meme economy 已经价值 2.5亿美元了。

The meme economy is where FOMO meets YOLO. — Felix Salmon from AXIOS

现在谁的手机还没存几个表情包 meme 呢?

然而,找到合适的 meme 需要时间。程序员之间的调侃对常规创作者来说还是比较偏僻。那程序员自己做一个允许任何人自定义 meme 并生成新 meme 的 web 应用程序怎么样?这就是Meme as a service 😎。

这样,妈妈再也不用担心我斗图输了!开干!

在这里插入图片描述

为什么要用 serverless

作为开发者,创建一个在图片上添加文本标题的 Web 应用程序可能并不困难。但是,“meme as a service”还有一些其他要求。

  • 图像处理任务通常需要大量计算,并且需要高性能。
  • meme 这种场景要么使用的人数很少,要么可能会迅速普及。换句话说,meme as a service 需要具有可伸缩性,而开发者只需为实际使用付费。

上述问题的解决方案如下。首先,我们要使用高性能的现代编程语言来编写图像和文本操作函数。因此我们选择了 Rust,Rust 提供了本机性能,同时又具有内存安全性。

接下来,使用公共云中的 serverless 函数可以最好地解决可伸缩性要求。serverless 函数在没有人使用的时候是免费的,并且可以迅速扩展到数百万个用户。

虽然可以将从 Rust 编译的本机程序作为 serverless 函数运行,但更好的方法是在 WebAssembly 虚拟机中作为 serverless 函数运行 Rust 程序。 WebAssembly 虚拟机充当本机应用程序与 serverless 主机环境之间的兼容层和安全沙箱。由于 WebAssembly 虚拟机已经经过预先配置,可以在公有云的 serverless 运行时的各种老旧的操作系统和容器映像中运行,因此它使 Rust 程序更具可移植性。此外,WebAssembly 使 Rust 程序可以轻松安全地访问以 C / C ++编写的软件库。一个示例是从 Rust 访问旧版操作系统中的Tensorflow 库。

快速开始

在这篇文章里,我会使用GitHub 上的模板函数 tencent-meme-scf 来在腾讯云上部署 Rust meme-as-a-service。这个模板基于开源的 Serverless Framework。Rust 程序编译成 Wasm 字节码并运行在 SSVM 上。SSVM 已经为基于云的运行环境进行了优化。

在这个例子

首先,你需要安装 Serverless Framework ,并在腾讯云上创建一个账号。腾讯云会提供免费的额度给开发者使用。接下来是 fork 或 clone 我们提供的模板函数,然后转到 tencent-meme-scf。

$ git clone https://github.com/second-state/tencent-meme-scf
$ cd tencent-meme-scf

使用 Serverless Framework 部署云函数、用于函数服务的 API 网关、让用户使用函数服务的静态 HTML 页面。 .env 文件里配置了要将函数部署到腾讯云。 只需按照屏幕上的说明,登录腾讯云并部署。

$ sls deploy
... ...region:  ap-hongkongwebsite: https://sls-website-ap-hongkong-3wxv81e-1302315972.cos-website.ap-hongkong.myqcloud.com
60s › tencent-meme-scf › "deploy" ran for 2 apps successfully.

在浏览器加载 website URL,来看看你的 meme-as-a-service! 你可以自定义 meme 图片上的每个标题/水印的文本、大小和位置。

表情包生成原理解析

这个应用程序的总体结构是一个典型的 JAMStack 应用程序。用于图像处理的后端逻辑被部署为 serverless 函数,并且可以通过API 使用。前端用户界面是静态 HTML 和 JavaScript 网页。前端通过 JavaScript Ajax 调用与后端 API 进行交互。

main.rs 是为 meme 图片添加文字的后端 serverless 函数,是用 Rust 编写的。它先读取文本/水印的字体文件和背景图像文件。

然后,Rust 函数读取用户在 HTML 网页中输入的文本、位置和大小。输入为 JSON 文本形式, serde_json 库将 JSON 文本解析为 Rust 结构的数组。

_watermark() 函数将每个水印添加到图像。_watermark() 函数输出最终的图像并对其进行 base64 编码。serverless 运行时的 API 网关将 base64 编码的图像返回给调用JavaScript,以显示在网页上。

const FONT_FILE : &[u8] = include_bytes!("PingFang-Bold.ttf") as &[u8];
const TEMPLATE_BUF : &[u8] = include_bytes!("bg.png") as &[u8];fn main() {let mut buffer = String::new();io::stdin().read_to_string(&mut buffer).expect("Error reading from STDIN");let obj: FaasInput = serde_json::from_str(&buffer).unwrap();let mut img = image::load_from_memory(TEMPLATE_BUF).unwrap();let memes: Vec<Watermark> = serde_json::from_str(&(obj.body)).unwrap();for m in memes {_watermark(m, &mut img);}let mut buf = vec![];img.write_to(&mut buf, image::ImageOutputFormat::Png).unwrap();println!("{}", base64::encode_config(buf, base64::STANDARD));
}

= _watermark() 函数在图像上添加了一条水印文本,这里用了标准的 Rust 图像处理库(Crate)来处理 meme 图像。

fn _watermark(w: Watermark, img: &mut image::DynamicImage) {let font_size = w.font_size;let font = Vec::from(FONT_FILE);let font = Font::try_from_vec(font).unwrap();let scale = Scale {x: font_size + 1.0,y: font_size + 1.0,};drawing::draw_text_mut(img, image::Rgba([0, 0, 0, 255u8]), w.left - 2, w.top - 2, scale, &font, &w.text);let scale = Scale {x: font_size,y: font_size,};drawing::draw_text_mut(img, image::Rgba([255u8, 255u8, 255u8, 255u8]), w.left, w.top, scale, &font, &w.text);
}

前端 JavaScript 从 HTML 表单中获取用户输入的文本、位置和字体大小,将输入数据以 JSON 提交到云函数,然后显示返回的base64 图像。

var memes = [];
memes[0] = {};
memes[0].text = $('#red-girl-says').val();
memes[0].left = parseInt($('#red-girl-left').val());
memes[0].top = parseInt($('#red-girl-top').val());
memes[0].font_size = parseInt($('#red-girl-font').val());
... ...$.ajax({url: window.env.API_URL,type: "post",data : JSON.stringify(memes),dataType: "text",success: function (data) {const img_url = "data:image/png;base64," + data;$('#wm_img').prop('src', img_url);},error: function(jqXHR, exception){console.log("Error Status: " + jqXHR.statusText);}
`});`

创建你的 meme

你可以使用源代码模板来创建你自己的 meme-as-a-service。 你可以更改 meme 背景图像,并更改用于添加文本水印的 UI。 因此,请首先确保已安装 Rust 编译器和 ssvmup 构建工具。

更改 Rust 代码和 HTML 文件来适配你自己的 meme 文件。将 Rust 代码编译成 WebAssembly,并把结果复制到 scf/ 文件夹

$ ssvmup build --enable-aot
$ cp pkg/scf.so scf/

运行 Serverless Framework 命令,部署函数。

$ sls deploy
... ...region:  ap-hongkongwebsite: https://sls-website-ap-hongkong-3wxv81e-1302315972.cos-website.ap-hongkong.myqcloud.com
60s › tencent-meme-scf › "deploy" ran for 2 apps successfully.

接下来

你可以用 JAMStack 应用和 serverless 函数做很多事情。例如,为TensorFlow 推理创建 serverless 函数,将图像识别和图片识别集成到 web 应用中。

创建你自己的 meme 图片,并提交 PR 给我们,填写这份问卷我们将为你送上一份精美礼品!

这篇关于斗图不用怕!用 serverless 随时创建你的表情包的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/403456

相关文章

idea中创建新类时自动添加注释的实现

《idea中创建新类时自动添加注释的实现》在每次使用idea创建一个新类时,过了一段时间发现看不懂这个类是用来干嘛的,为了解决这个问题,我们可以设置在创建一个新类时自动添加注释,帮助我们理解这个类的用... 目录前言:详细操作:步骤一:点击上方的 文件(File),点击&nbmyHIgsp;设置(Setti

Spring 中使用反射创建 Bean 实例的几种方式

《Spring中使用反射创建Bean实例的几种方式》文章介绍了在Spring框架中如何使用反射来创建Bean实例,包括使用Class.newInstance()、Constructor.newI... 目录1. 使用 Class.newInstance() (仅限无参构造函数):2. 使用 Construc

C#原型模式之如何通过克隆对象来优化创建过程

《C#原型模式之如何通过克隆对象来优化创建过程》原型模式是一种创建型设计模式,通过克隆现有对象来创建新对象,避免重复的创建成本和复杂的初始化过程,它适用于对象创建过程复杂、需要大量相似对象或避免重复初... 目录什么是原型模式?原型模式的工作原理C#中如何实现原型模式?1. 定义原型接口2. 实现原型接口3

Python中conda虚拟环境创建及使用小结

《Python中conda虚拟环境创建及使用小结》本文主要介绍了Python中conda虚拟环境创建及使用小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录0.前言1.Miniconda安装2.conda本地基本操作3.创建conda虚拟环境4.激活c

使用Python创建一个能够筛选文件的PDF合并工具

《使用Python创建一个能够筛选文件的PDF合并工具》这篇文章主要为大家详细介绍了如何使用Python创建一个能够筛选文件的PDF合并工具,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录背景主要功能全部代码代码解析1. 初始化 wx.Frame 窗口2. 创建工具栏3. 创建布局和界面控件4

Java中对象的创建和销毁过程详析

《Java中对象的创建和销毁过程详析》:本文主要介绍Java中对象的创建和销毁过程,对象的创建过程包括类加载检查、内存分配、初始化零值内存、设置对象头和执行init方法,对象的销毁过程由垃圾回收机... 目录前言对象的创建过程1. 类加载检查2China编程. 分配内存3. 初始化零值4. 设置对象头5. 执行

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

Python创建Excel的4种方式小结

《Python创建Excel的4种方式小结》这篇文章主要为大家详细介绍了Python中创建Excel的4种常见方式,文中的示例代码简洁易懂,具有一定的参考价值,感兴趣的小伙伴可以学习一下... 目录库的安装代码1——pandas代码2——openpyxl代码3——xlsxwriterwww.cppcns.c

使用Python在Excel中创建和取消数据分组

《使用Python在Excel中创建和取消数据分组》Excel中的分组是一种通过添加层级结构将相邻行或列组织在一起的功能,当分组完成后,用户可以通过折叠或展开数据组来简化数据视图,这篇博客将介绍如何使... 目录引言使用工具python在Excel中创建行和列分组Python在Excel中创建嵌套分组Pyt

解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题

《解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题》文章详细描述了在使用lombok的@Data注解标注实体类时遇到编译无误但运行时报错的问题,分析... 目录问题分析问题解决方案步骤一步骤二步骤三总结问题使用lombok注解@Data标注实体类,编译时