Rust 赋能前端 -- 写一个 File 转 Img 的功能

所有耀眼的成绩,都需要苦熬,熬得过,出众;熬不过,出局

大家好,我是柒八九。一个专注于前端开发技术/RustAI应用知识分享Coder

此篇文章所涉及到的技术有

  1. Rust
  2. wasm-bindgen/js-sys/web-sys
  3. Web Worker
  4. WebAssembly
  5. Webpack/Vite配置WebAssembly
  6. OffscreenCanvas
  7. 脚手架生成项目(npx f_cli_f create xxx
  8. tailwindcss
  9. MuPDF.js/mammoth.js

因为,行文字数所限,有些概念可能会一带而过亦或者提供对应的学习资料。请大家酌情观看。


前言

在前一篇文章写一个类ChatGPT应用,前后端数据交互有哪几种我们介绍了,如果要进行一个类ChatGPT应用的开发,可能会用到的前后端数据交互的方式。同时呢,我们也介绍了最近公司所做的项目,做一款基于文档类问答的AI功能。

而谈到文档相关的应用,从操作文档角度来看,无非就是文件上传文件解析文件展示。而我们之前在文件上传 = 拖拽 + 多文件 + 文件夹介绍过更优雅的上传方式。而文件展示如果大家想了解的话,我们可以单独写一篇文章。

而我们今天来聊聊关于文件解析的相关操作。

业务背景

大家肯定用过很多云盘类的应用。在我们对本地文件进行上传后,在展示的时候一般分为两种模式

  1. 列表模式
    列表模式
  2. 大图模式
    大图模式

如果大家观察过云盘针对大图模式的文件资源的展示,就会发现每个文件的头图都是用一个<img/>接收了一个从后端返回的固定图片资源。

而现在,我们针对大图模式有几点改进

  1. 要求该图片能显示文件资料的概要内容(这块可以借助AI对文本进行Summary处理,这个我们后面会单独写一篇文章),而不是单单的把文件的首页信息(pdf/word/pptx)转换成图片(像阿里云盘一样)
  2. 要求前端在上传过程中,就需要显示文件的概要信息,而不是走接口从服务器获取,也就是这是一个纯前端的事情
  3. 还需要在图片的标识文件的类型,例如展示pdf/word/ppt等的图标

为什么做呢,有没有发现我们通过上述的改造和处理,我们直接在大图模式下,通过文件头图信息就能大致知晓文件的内容(概要信息),其次如果展示的资源信息过多,每次从后端获取对应的图片资源也是一件极其耗费带宽的事情。

前端糅合其他语言

讲到这里,大家可能会疑惑,你上面说了那么多,那么这和Rust有啥关系?

关系大着呢,从上面的需求点出发,我们可以看出,其实针对文档解析的处理,都是在前端环境中操作的。同时,针对大体积的文件资源,对其解析处理是一件极其耗时的事情。有时针对特殊文件,可能前端还暂时无法处理。

既然,我们想要在前端执行这些耗时且不易处理的任务,我们就需要请帮手,而在其他语言中有成熟的方案来处理我们遇到的这些问题。(由于种种原因,其他端的小伙伴无瑕处理这种情况)

那么,我们就可以选择一种方式,在前端环境中通过某种方式来糅合其他语言的操作来执行对应的任务。那思来想去,WebAssembly是再合适不过的方式了。如果不了解它,可以看我们之前的文章 - 浏览器第四种语言-WebAssembly。

当然,其他语言(C/TypeScript)都可以通过编译工具转化成WebAssembly,此片文章中也会涉及,只不过我们是直接使用别人构建好的WebAssembly,而现行阶段,Rust是对WebAssembly最友好的语言。并且,我们也会用Rust手搓一个WebAssembly。这也是为什么这篇文章的主标题叫Rust赋能前端而不是WebAssembly赋能前端(我们在本文的第三部分,Word 解析中详细介绍了用RustWebAssembly,如果不想看mupdf的可以直接跳到第三节)

好了,天不早了,干点正事哇。

我们能所学到的知识点

  1. 服务配置&项目配置
  2. PDF 解析
  3. Word 解析

1. 服务配置&项目配置

由于,WebAssembly是一个新兴技术,在一些常规的打包工具(vite/webpack)中使用,我们需要额外处理。

使用WebAssembly从来源大致可以两类

  1. npm包/公司私包(针对如何发私包可以参考之前的如何在gitlab上发布npm包)
  2. 直接在项目目录中使用已经构建好的wasm

这两种情况我们接下来都会涉及。其实他们的处理方式都是一样的。下面我们就来讲讲Webpack/Vite是如何配置它们的。

Webpack

针对Webpack中使用WebAssembly,我们之前在Rust 编译为 WebAssembly 在前端项目中使用就介绍过。

其实,最关键的点就是需要wasm-pack-plugin

其次,我们还想让WebAssembly模块能够和其他ESM一样,通过import进行方法的导入处理,针对Webapck5我们还可以通过配置experiments的asyncWebAssembly为true来启动该项功能。

最后,为了兼容性,我们处理TextEncoder/TextDecoder

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const WasmPackPlugin = require("@wasm-tool/wasm-pack-plugin");module.exports = {entry: './index.js',output: {path: path.resolve(__dirname, 'dist'),filename: 'index.js',},plugins: [new HtmlWebpackPlugin({template: 'index.html'}),new WasmPackPlugin({crateDirectory: path.resolve(__dirname, ".")}),// 让这个示例在不包含`TextEncoder`或`TextDecoder`的Edge浏览器中正常工作。new webpack.ProvidePlugin({TextDecoder: ['text-encoding', 'TextDecoder'],TextEncoder: ['text-encoding', 'TextEncoder']})],mode: 'development',experiments: {asyncWebAssembly: true}
};

Vite

Vite官网看,它只兼容了引入预编译的.wasm,但是对 WebAssemblyES 模块集成提案 尚未支持。而恰巧,我们今天所涉及到的.wasm都是ESM格式的。

按照官网的提示,我们可以借助vite-plugin-wasm的帮助。

配置也很简单,按照下面的处理即可。

import wasm from "vite-plugin-wasm";
import topLevelAwait from "vite-plugin-top-level-await";export default defineConfig({plugins: [wasm(),topLevelAwait()],worker: {plugins: [wasm(),topLevelAwait()]}
});

项目配置

由于,我们公司的打包工具是Vite,还记得我们之前介绍过的脚手架工具吗。

大家可以在自己电脑中执行,npx f_cli_f create file_to_img来构建一个以Vite为打包工具的前端项目。

然后,我们就可以将上面逻辑写到对应的文件中。

执行到这里,我们的前期的配置工作就算完成了。

如果使用过我们的f_cli_f的人,会知道。我们在项目中内置了很多东西,可以算是开箱即用。

所以,我们保留之前的结构的基础上,在pages中新建一个FileToImg的目录结构,并且将其放置于main路由下。

最后的页面结构如下

  • 左侧的待处理文件类型我们提供了针对pdf/word/text的常规文件的解析
  • 附件上传就是使用最原始的<input type="file"/>
  • 搜索区块的话,是针对PDF的内容检索
  • 右侧的格式输出,可以切换文件的输

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/15057.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

校园二手书交易|基于SprinBoot+vue的校园二手书交易管理系统(源码+数据库+文档)

校园二手书交易管理系统 目录 基于SprinBootvue的校园二手书交易管理系统 一、前言 二、系统设计 三、系统功能设计 1系统功能模块 2管理员功能模块 3 卖家用户功能模块 4 用户功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八…

Linux:iptables防火墙部署优化之连接转移(目的地地址转化)

Linux&#xff1a;iptables防火墙部署优化之连接转移&#xff08;目的地地址转化&#xff09; 文章目录 Linux&#xff1a;iptables防火墙部署优化之连接转移&#xff08;目的地地址转化&#xff09;node1操作检测ip情况关闭firewalld防火墙服务&#xff0c;并锁定该服务开启ip…

什么是分布式会话

分布式会话是指在分布式系统中实现用户会话管理的一种机制。在传统的单服务器架构中&#xff0c;用户的会话数据通常存储在单个服务器或应用服务器的内存中。然而&#xff0c;随着业务的发展和用户量的增加&#xff0c;单服务器架构往往无法满足高可用性和高并发的需求&#xf…

Minio WebUploader上传文件的高级用法之进度条显示、文件过滤、图片预览、图片压缩

系列文章目录 第十章 Minio WebUploader上传文件的高级用法之进度条显示、文件过滤、图片预览、图片压缩 Minio WebUploader上传文件的高级用法之进度条显示、文件过滤、图片预览、图片压缩 系列文章目录进度条显示文件过滤图片预览图片压缩 进度条显示 使用进程文件上传时&a…

基于springboot+html的二手交易平台(附源码)

基于springboothtml的二手交易平台 介绍部分界面截图如下联系我 介绍 本系统是基于springboothtml的二手交易平台&#xff0c;数据库为mysql&#xff0c;可用于毕设或学习&#xff0c;附数据库 部分界面截图如下 联系我 VX&#xff1a;Zzllh_

java Iterable和 Iterator接口区别和联系

Iterable 和 Iterator 是 Java 集合框架中用于遍历集合元素的两个接口,它们之间既有区别也有联系。下面详细介绍它们的区别和联系。 Iterable 接口 定义 Iterable 接口位于 java.lang 包中,定义如下: public interface Iterable<T> {Iterator<T> iterator()…

在家庭影院音频中应用的D类音频放大器

家庭影院的主要组成部分包括显示设备、音响设备、信号源和接线设备等。家庭影院的音响信号需要进行处理和输出&#xff0c;以获得高质量的音效。音响设备通常需要一台功率适当的数字、模拟混合的处理器&#xff0c;对音源进行降噪、均衡、扩展等处理操作&#xff0c;以达到高品…

核心交换机与终端通信正常,接入交换机无法Ping通同一VLAN内终端

环境: 思科3560交换机 问题描述: 核心交换机与PC通信正常,接入交换机无法Ping通同一VLAN内PC h3c核心交换机配置vlan2 vlanif2 IP192.168.1.1 下挂接入交换机配置了vlan2 pc接到接入交换机25口这个端口配置access vlan2,pc的ip是192.168.1.3从 核心交换机上ping192.168.…

【智能算法应用】北方苍鹰算法求解二维栅格路径规划问题

目录 1.算法原理2.二维路径规划数学模型3.结果展示4.参考文献5.代码获取 1.算法原理 【智能算法】北方苍鹰优化算法&#xff08;NGO)原理及实现 2.二维路径规划数学模型 栅格法模型最早由 W.E. Howden 于 1968 年提出&#xff0c;障碍物的栅格用黑色表示&#xff0c;可通过的…

ping 探测网段哪些地址被用

#!/bin/bash# 遍历192.168.3.1到192.168.3.254 for i in {1..254} doip"192.168.3.$i"# 对每个IP地址进行三次ping操作if ping -c 3 -W 1 $ip > /dev/null 2>&1thenecho "$ip: yes"fi done$ sh test.sh 192.168.3.1: yes 192.168.3.95: yes 192.…

使用Word表格数据快速创建图表

实例需求&#xff1a;Word的表格如下所示&#xff0c;标题行有合并单元格。 现在需要根据上述表格数据&#xff0c;在Word中创建如下柱图。如果数据在Excel之中&#xff0c;那么创建这个图并不复杂&#xff0c;但是Word中就没用那么简单了&#xff0c;虽然Word中可以插入图表&a…

014_C标准库函数之<stdio.h>

【背景】 今天这个主要说的是<stdio.h>头文件&#xff0c;大家众所周知&#xff0c;这个是我们学习C语言时第一个接触到的头文件了&#xff0c;那么为什么我不一开始就介绍这个头文件呢&#xff1f;我觉得有两个原因&#xff0c;如下&#xff1a; 1.一开始大家的编程思…

LeetCode/NowCoder-链表经典算法OJ练习3

孜孜不倦&#xff1a;孜孜&#xff1a;勤勉&#xff0c;不懈怠。指工作或学习勤奋不知疲倦。&#x1f493;&#x1f493;&#x1f493; 目录 说在前面 题目一&#xff1a;返回倒数第k个节点 题目二&#xff1a;链表的回文结构 题目三&#xff1a;相交链表 SUMUP结尾 说在前…

Pytorch: 解决因pytorch版本不同 导致训练ckpt加载失败

大家都会遇到在工程项目实施阶段&#xff0c;如果训练的模型文件在不同的torch版本环境下部署时&#xff0c;会报错~。 报错举例 # 查看torch环境 import torch print(torch.__version__)# 训练时环境&#xff1a;torch 1.8.2cu111 # 部署时环境&#xff1a;torch 1.4.0torch.…

dcatAdmin框架 使用phpword 生成word文件

下载phpword插件 composer require phpoffice/phpword 生成word文件接口 static public function word(){//接收传值$order_id request()->get(order_id);$tpl_id request()->get(tpl_id);//查询出对应的数据以及关联数据$sale_order \App\Models\SaleOrder::with([…

Python异步编程之基础概念

Python异步编程之基础概念 在现代编程中&#xff0c;异步编程是一种重要的技术&#xff0c;尤其是在处理I/O密集型任务时&#xff0c;异步编程可以大大提高程序的性能和响应速度。本文将介绍Python异步编程的基础概念&#xff0c;帮助你理解其原理和应用。 什么是异步编程&am…

【代码随想录算法训练营第37期 第十七天 | LeetCode110.平衡二叉树、257. 二叉树的所有路径、404.左叶子之和】

代码随想录算法训练营第37期 第十七天 | LeetCode110.平衡二叉树、257. 二叉树的所有路径、404.左叶子之和 一、110.平衡二叉树 解题代码C&#xff1a; /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *righ…

三、NVIDIA Jetson Orin开发板-GPU加速

一、NVIDIA Jetson Orin开发板的硬件情况 df -h#查看操作系统情况Filesystem Size Used Avail Use% Mounted on **/dev/nvme0n1p1** 234G 17G 208G 8% / none 7.4G 0 7.4G 0% /dev tmpfs 7.6G 0 7.6G 0% /dev/shm tmpfs …

LeetCode 2644.找出可整除性得分最大的整数:暴力模拟(两层循环)

【LetMeFly】2644.找出可整除性得分最大的整数&#xff1a;暴力模拟&#xff08;两层循环&#xff09; 力扣题目链接&#xff1a;https://leetcode.cn/problems/find-the-maximum-divisibility-score/ 给你两个下标从 0 开始的整数数组 nums 和 divisors 。 divisors[i] 的 …

MySQL库/表/数据的操作

文章目录 1.数据库操作1.1 创建、删除、查看和修改1.2 编码格式1.3 备份和恢复 2.表的操作2.1 创建表2.2 存储引擎2.3 查看表、修改表、删除表 3.数据类型3.1整数类型3.2字节类型(bit)3.3浮点类型(bit)3.4 decimal3.5 字符串类型3.6 日期和时间类型3.7 enum和set关于如何查找想…