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的内容检索
  • 右侧的格式输出,可以切换文件的输

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[AI Google] I/O 2024大会上我们宣布的100件事情

I/O 2024 发生了很多事情&#xff01;无论你对最新的 Gemini 应用更新感兴趣&#xff0c;对开发者即将推出的内容感到特别兴奋&#xff0c;还是迫不及待想尝试最新的生成式 AI 工具&#xff0c;这里几乎为每个人都提供了一些内容。不信&#xff1f;以下是我们在过去两天宣布的 …

如何使用 Monte Carlo 模拟作为项目管理工具

Monte Carlo 模拟是一种预测不确定事件可能结果的数学技术。我们之前曾撰写过有关其为研发专业人员带来的益处的文章&#xff0c;并主持过有关 Monte Carlo 模拟功能的网络讲座&#xff0c;以帮助产品满足预期规格、预测过程能力并确定最佳过程设置。然而&#xff0c;Monte …

隐藏服务器源IP怎么操作,看这一篇学会!

在当今的网络环境中&#xff0c;服务器作为信息和服务的中枢&#xff0c;常驻于公网之上&#xff0c;面临着各式各样的安全威胁&#xff0c;其中&#xff0c;分布式拒绝服务&#xff08;DDoS&#xff09;攻击尤为猖獗&#xff0c;它通过协调大量计算机同时向目标服务器发送请求…

打印机手动双面打印技巧

一、WORD和PDF &#xff08;1&#xff09;首先选择要打印的页面范围&#xff0c;然后选择仅奇数页打印 &#xff08;2&#xff09;将打印完的纸张翻过来&#xff0c;白纸朝上&#xff0c;纸张的头部先放入打印机 &#xff08;3&#xff09;选择要打印的页面范围&#xff0c;然…

【算法】递归、搜索与回溯——汉诺塔

题解&#xff1a;汉诺塔(递归、搜索与回溯算法) 目录 1.题目2.题目背景(拓展了解)3.题解4.参考代码5.细节6.总结 1.题目 题目链接&#xff1a;LINK 2.题目背景(拓展了解) 汉诺塔问题是一个通过隐式使用递归栈来进行实现的一个经典问题&#xff0c;该问题最早的发明人是法国…

从零教你实现django的前后端分离模式文件上传下载功能实现(2024最新)

文章目录 项目初始化配置具体文件上传下载代码的实现数据库模型类建立 运行测试 项目初始化配置 1.使用pycharm编辑器新建一个django项目 2.Terminal终端下载需要的依赖包 # 和数据库建立连接的依赖包 pip install mysqlclient # 解决跨域问题的依赖包 pip install django-co…

使用阿里云OSS实现视频上传功能

目录 前言 视频上传 前言 阿里云对象存储服务&#xff08;OSS&#xff09;作为一种高可用、高扩展性的云端存储服务&#xff0c;为开发者提供了便捷、安全的对象存储解决方案。本文将介绍如何利用阿里云OSS实现视频上传功能。 视频上传 前期准备请看阿里云OSS文件上传和下载…

颜色空间的选择

1.选择Gamma颜色空间&#xff0c;Web平台或者不支持线性空间&#xff0c;或者追求高饱和度的 2.选择Linear&#xff0c;追求真实光照和物理准确

9、C#【进阶】特性

特性 文章目录 1、特性概念2、自定义特性 Attribute3、特性的使用4、限制自定义特性的使用范围5、系统自带特性1、过时特性2、调用者信息特性3、条件编译特性4、外部dll包函数特性 1、特性概念 特性是一种允许我们向程序的程序集添加元数据的语言结构 它是用于保存程序机构信息…

Springboot启动时报错Property ‘mapperLocations‘ was not specified.

这几天没整boot 晚上直接运行不了了 本想是在表现层写点代码测测接口的 localhost8080找半天 结果404 先考虑好久 是不是url输入错了 然后 就发现 结果boot都不能启动了 JUnit也测不出来 找了半天 结果是开关机导致数据库没开 手动打开服务 找到MySQL启动 IDEA连接数据…

Istio ICA考试之路---2-6

Istio ICA考试之路---2-6 1. 题目2. 解题2.1 获取模板2.3 整理yaml 3. 测试 1. 题目 Using Kubernetes context cluster-2 Create and configure Istio resources necessary for routing all traffic destined for http://example.org through the default Istio egress gat…

PLC远程调试

随着工业自动化的快速发展&#xff0c;PLC&#xff08;可编程逻辑控制器&#xff09;已经成为现代工业生产线的核心控制设备。然而&#xff0c;传统的PLC调试方式往往受限于地理位置和物理连接&#xff0c;使得工程师在调试过程中面临诸多不便。在这个背景下&#xff0c;HiWoo …

河道流量监测解决方案 河道水位监测 水质在线监测-计讯物联科技

在城市河道与入海口间的通道施工项目中&#xff0c;拦水坝不仅承担着调节水流、保护生态平衡的使命&#xff0c;也是确保施工区域安全的关键屏障。当前&#xff0c;项目团队面临着严峻的挑战&#xff1a;水位的异常上升和流量的急剧变化&#xff0c;这些都可能对拦水坝的稳定性…

YOLO训练报错解决:OSError: [WinError 1455] 页面文件太小,无法完成操作

问题&#xff1a;OSError: [WinError 1455] 页面文件太小&#xff0c;无法完成操作。 Error loading "C:\Users\12706.conda\envs\yolov8\lib\site-packages\torch\lib\cudnn_cnn_infer64_8.dll" or one of its dependencies. 解决方法&#xff1a; 降低数据加载的线…

SpringSecurity登录和校验流程简述

认证&#xff1a; 验证当前访问系统的是不是本系统的用户&#xff0c;并且要确认具体是哪个用户 授权&#xff1a; 经过认证后判断当前用户是否有权限进行某个操作 一、入门案例实现 搭建springboot工程后&#xff0c;创建启动类和Controller&#xff0c;引入SpringSecurity依…

Spring Cache基本使用

Spring 从 3.1 版本开始定义缓存抽象来统一不同的缓存技术&#xff1b;在应用层面与后端存储之间&#xff0c;提供了一层抽象&#xff0c;这层抽象目的在于封装各种可插拔的后端存储( ehcache, redis, guava)&#xff0c;最小化因为缓存给现有业务代码带来的侵入。 一、Spring…

【代码随想录】面试常考类型之动态规划01背包

前言 更详细的在大佬的代码随想录 (programmercarl.com) 本系列仅是简洁版笔记&#xff0c;为了之后方便观看 不同的二叉搜索树 96. 不同的二叉搜索树 - 力扣&#xff08;LeetCode&#xff09; 通过举例子发现重叠子问题 代码很简单&#xff0c;主要是思路问题&#xff0…

AD使用问题

设计流程&#xff1a; 1.先创建项目——添加原理图&#xff0c;原理图库&#xff0c;PCB&#xff0c;PCB库 2.画原理图库和封装库 主要有三种方法&#xff1a; &#xff08;1&#xff09;手动画库和封装&#xff0c;常常用于嘉立创查询不到的器件 &#xff08;2&#xff0…

spark的简单学习二

一 spark sql基础 1.1 Dataframe 1.介绍&#xff1a; DataFrame也是一个分布式数据容器。然而DataFrame更像传统数据库的二维表 格&#xff0c;除了数据以外&#xff0c;还掌握数据的结构信息&#xff0c;即schema。同时&#xff0c;与Hive类似&#xff0c;DataFrame也支 持…

6、xss-labs之level8

1、测试分析 传入123查看页面源码&#xff0c;发现传入的值传给了value和a标签的href&#xff0c;并且对特殊字符<>" 都进行了HTML实体化&#xff0c;对于大小写进行了转化&#xff0c;过滤掉了src、data、onfocus、href、script、"&#xff08;双引号&#…