作者 : 汤玄 (卡内基梅隆大学计算机专业,ArcBlock夏季实习生)

导师 : 张晗(ArcBlock,工程师/实习生导师)

这个夏天我在 ArcBlock 进行了为期 3 个月的实习。在此期间,我学习了与网络开发相关的知识,包括 React 和 Node.js。有了这些基础,我阅读了 ArcBlock 给开发者提供的文档,对 ArcBlock 的 blocklet 平台有了一定程度的了解之后,我专注于完成一个可以根据模版生成定制化图片的 Decentralized App (DApp)。在这篇博客中,我将简单介绍一下这个项目。

为什么需要去中心图片生成器

在某些类型的网站应用中,常常会需要用到大量产生自模版的图片, 如电商网站的模版化产品图片,用于社交分享的活动图片,用于搜索引擎和社交链接优化的Open Graph图片等等。 这时候采用一个基于模版的图片生成器要比让设计师一张张去设计生产图片有效率得多。 在过去已经有不少服务能帮助用户完成这些工作,但其缺点是这样你的站点就会依赖这些第三方服务。

去中心图片生成器就是把这样的基于模版的图片生成服务变成一个可组合的Blocklet,任何需要用的网站可以安装和组合自己的图片生成器,不再有任何第三方的服务依赖。

设计

这个图片生成器分为主页和编辑页两个界面。主页主要是让用户去选择自己想要的模板。如下图所示,模版一共有 5 个主题:教育类、科技类、娱乐类、金融类、环境类,每个主题里有 6 个模板供选择。选好了之后,用户将进入编辑页界面。

page home

编辑页分为标题区、预览区、参数编辑区和功能区,下面我将一一介绍这 4 个部分。

标题区和预览区

page playground 1

如上图所示,左上角是一个可以返回到主页的按钮,和居中的文字构成标题区。下面展示图片的是预览区,初始状态下展示的是用户选择的模板。之后用户只要在参数编辑区修改图片的参数或者添加文字,变化将及时展现在预览区中呈现给用户。

参数编辑区

page playground 2

参数编辑区里一共分为 5 个部分,对应着图片 5 个类型的参数。

参数区 1: 在左上角的区域里,用户可以调节图片的尺寸,也就是图片的宽和高。它们的初始值将是模板的原始尺寸。在 2 个输入框下,还有一个可供用户勾选的选项——是否要保持图片的原始宽高比。如果用户勾选了这个选项,那么他只需要更改宽和高的其中一个参数,另一个参数会根据比例自动进行调整。

参数区 2: 由于用户经常需要在图片上加入文字来丰富图片能表达的信息,所以我们提供了这个参数区来让用户在图片上添加文字。用户可以在这个区域里输入想加入的文字,该输入框支持换行/添加空格。

参数区 3: 随着用户加入文字,接下来 3 个参数区将围绕文字的格式供用户进行调整。首先,用户可以通过在文本框中输入一个数字来调节文字的大小。在这个参数区中,用户还可以调整文字的位置。“Top margin”代表了文字到图片顶部的距离,而“Left margin”则代表了文字到图片左侧的距离。

参数区 4: 在第二行最左侧的区域里,用户可以选择文字的字体。点开复选框可以展示所有的字体,初始值将是为多数人所使用的 Arial 字体。

参数区 5: 最后用户可以调节文字的颜色。用户需要先在参数区域内的颜色条上挑选一个大致的颜色方向,之后再在下方 5 个颜色中选择一个具体的。



由于以上功能牵涉到的基本是前端,我运用了 React 去实现。每个参数区对应着 React 的一个 component,方便管理。每个参数则对应着 React 的一个 state,从而便于通过输入框/复选框区调整。这些输入框调用了 MUI 组件库增加了美观性。有了这些参数,只需要将它们传入 html 和 css style 中,即可在预览区中呈现出来。

具体生成图片可供用户下载这个功能则是调用了 html2canvas 这个库去实现。html2canvas 将会对预览区的图片进行截图,并将截出来的图片返回,保证用户最终得到的图片和预览区中所展示的一致。

功能区

page playground 3

功能区由 2 个按钮构成,分别提供了下载图片和分享图片 2 个功能。

当用户点击了 Download 按钮之后,上文提到的 html2canvas 库会对预览区里展示的图片进行截图这个操作,并将截出来的图下载到用户本地。

而当用户点击了 Share 按钮之后,下方将会出现一个代表图片地址的 URL,用户可以复制这个链接,从而在自己需要的地方放入这个图片 URL,无需下载即可将图片分享给他人。当然这个图片也和预览区所展示的图片一致。

分享图片这个功能牵涉到后端的服务器部分,这里主要运用了 Express.js 框架去实现。首先,我们需要将前端预览区中的图片的所有参数作为一个 URL 先传到后端,这里我借助了 axios 这个库。在后端,我用了一个 router 去接受前端传来的 URL 并且将每个参数提取出来。之后我用了 canvas 这个库根据这些参数画出与前端一致的图片出来。画出来以后先用 toDataURL 将其转化为一个 base64 的 data URL,再把 base64 格式转化为 image。这样一来,我们在后端就成功拿到了用户在前端生成的图片。

在画图的时候由于需要去加载用户选择的模板,我们要先将所有的模板上传到服务器的静态资源中。因为整个 project 是用 create-blocklet 的模板创建的,我们可以将这些图片存到 blocklet 的 datadir 里。同样,在后端成功生成用户需要的图片之后,我也可以把它们写入到 datadir 里,并将其挂载到 assets 这个路径下。最后只需要向前端返回这个图片的路径 URL 即可。

源代码Git Repo 和 Blocklet Store

您可以直接去尝试一下,或者fork这些代码继续完善成真正可用的产品。

Github:https://github.com/dnfisreal/image-generator

Blocklet Store: https://test.store.blocklet.dev/blocklets/z8ia3a66nQ7eqpSbj37cZj6qNnsmMsuUkATmP

致谢

以上就是关于这个图片生成器的大致介绍。在这近三个月的实习过程中,我很高兴能完成一个 blocklet,我从中也学到了很多平时在学校接触不到的知识,再次感谢 ArcBlock 给我提供的这个机会!