如何使用JavaScript开发一款可将基于浏览器的图像故事板转换为PDF格式的工具
在任何人开始拍摄视频、制作广告或绘制漫画的最终画面之前,通常会先画出一份故事板草图:按照拍摄顺序为每一镜头绘制一幅图片,并附上简短的说明,说明该镜头中发生了什么以及持续时间有多长。 大多数人已经拥有这些图片了——它们可能是手机照片、截图、粗略的草图,或者是通过人工智能生成的图像文件,这些文件都保存在某个文件夹里。但他们所缺乏的是一种能够将这些文件快速整理成格式规范、编号整齐的文档,并将其打印出来或发送给客户的工具。 在这个教程中,你将学习如何制作这样一个基于浏览器的工具。你需要添加一组图片,为每张图片指定标题、描述和持续时间,选择合适的布局方式,预览生成的文档,然后下载可供打印的PDF文件。
- 这个图像故事板工具的功能及其工作原理
- 项目设置
- 所使用的库和浏览器API
- 创建HTML布局
- 添加并加载图片
- 管理图片帧
- 配置故事板设置
- 布局故事板页面
- 在画布上绘制图片
- 预览文档页面
- 使用IndexedDB保存草稿
- 利用PDF库生成PDF文件
- 重命名文件并下载结果
- 演示:这个图像故事板工具的工作原理
- 性能优化技巧
- 常见错误及解决方法
- 总结
- 一个标签,例如
镜头1或场景1 - 一个可选的标题
- 对所发生内容的描述
- 一个可选的时长(以秒为单位)
这些帧会被按照以下四种布局方式中的某一种排列在相应的页面上:
- 每页显示一帧,这样就可以将每一镜头放大展示
- 网格布局,可以让人一眼看到整个序列的内容
- 带注释的面板,面板上有横线,方便在拍摄现场手写注释
- 电影胶片条格式,带有齿孔,呈现出传统电影胶片的视觉效果
每页的顶部都会显示标题、总时长以及页面编号。
下面是整个制作过程的流程:
图片 → 帧(包含标题、描述和时长)
→ 布局设置(确定每个元素在PDF页面上的位置,以像素为单位)
→ 在画布上添加标签、文本和线条
→ 生成PDF文件(图片格式为JPEG,每页包含一层文本)
→ 下载PDF文件
为什么文本要绘制在画布上
PDF-lib工具确实可以将真实的文本嵌入到PDF文件中,但前提是必须使用预先嵌入的字体文件。标准的PDF字体仅支持基本的拉丁字符,因此如果需要用印地语、古吉拉特语、阿拉伯语或日语等语言进行描述,就会出现问题。
而画布则可以显示设备能够支持的任何文本,并且会使用设备本身已安装的字体。因此,这个工具会将所有文本以300dpi的分辨率绘制在画布上,然后再将这些画布图像嵌入到PDF文件中。
不过这样的做法会导致PDF中的文本无法被选中或搜索。对于主要用于打印和查看的故事板来说,这种格式通常已经足够使用了。但如果确实需要可搜索的文本,那么就应该使用PDF-lib工具提供的fontkit功能来嵌入相应的字体文件。
项目设置
你只需要准备三个文件即可:
image-storyboard/
├── index.html
├── style.css
└── script.js
请通过本地服务器来打开index.html文件(例如,可以使用VS Code中的Live Server扩展),而不是以file://的方式直接打开它,这样IndexedDB和下载功能才能像在真实网站上一样正常工作。
使用的库及浏览器API
这个项目使用了一个外部库以及一些内置的浏览器API:
- PDF-lib用于生成PDF文件,嵌入JPEG和PNG格式的图片,并保存最终文件。
- Canvas API用于绘制预览页面的内容以及PDF文件中的文本层。
createImageBitmap用于解码图片,并应用手机照片中存储的旋转参数。- IndexedDB帮助在浏览器中保存临时数据,这样在页面重新加载时也能保留之前的工作成果。
在这里不需要使用PDF.js,因为根本不存在需要读取的PDF文件。整个制作过程都是从处理图片开始的。
请在body标签的末尾添加PDF-lib库的固定版本链接,然后再放置你自己的脚本文件:
<script src="https://unpkg.com/pdf-lib@1.17.1/dist/pdf-lib.min.js"></script>
<script src="script.js"></script>
固定某个版本意味着,该库未来的任何更新都不会在您不知情的情况下破坏您的工具。
创建HTML布局
这个页面由四个部分组成:
- 一个用于上传文件的区域,其中包含文件输入框
- 一条用于恢复已保存草稿的按钮栏
- 一个框架面板,每个图像对应一个卡片
- 一个设置面板和一个预览面板
以下是上传区域和草稿恢复按钮栏的具体代码:
<!-- 1. 上传文件 -->
<section id="uploadArea" class="upload-area">
<p>将图片拖放到此处或
</p>
</section>
<div id="draftBar" class="draft-bar" hidden>
</div>
文件输入框仅接受所有浏览器都能解码的格式:JPEG、PNG、WebP和GIF。
工作区由以下三个面板组成:
<!-- 2. 工作区 -->
<section id="workspace" class="workspace" hidden>
框架布局
</span>
故事板标题
</ol>
设置面板由一系列select和number类型的输入框组成。每个输入框都有一个与之对应的idid会在您用JavaScript创建的设置对象中与相应的键匹配。
<div class="settings-panel">
界面设置