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

news2024/11/18 20:20:03

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

大家好,我是柒八九。一个专注于前端开发技术/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.coloradmin.cn/o/1692395.html

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

相关文章

win11缺少msvcr110dll,msvcp110.dll的解决办法

MSVCP110.dll是一个与Microsoft Visual C 2012 Redistributable Package相关的动态链接库&#xff08;Dynamic Link Library&#xff09;文件&#xff0c;主要用于支持使用C编写的Windows应用程序运行时所需的特定功能。当用户尝试运行依赖于这个库的应用程序时&#xff0c;如果…

【网络安全】网络安全协议的重要性

一.网络安全 1.什么是网络安全 网络安全&#xff08;Cyber Security&#xff09;是指网络系统的硬件、软件及其系统中的数据受到保护&#xff0c;不因偶然的或者恶意的原因而遭受到破坏、更改、泄露&#xff0c;系统连续可靠正常地运行&#xff0c;网络服务不中断。 2.网络安…

智慧展厅设计的难点有哪些

1、运用先进的展示技术 将全息影像、三维投影、虚拟现实、人机互动等技术做做完美衔接&#xff0c;把展厅的内容展示做到丰富多彩&#xff0c;从而让展厅富有科技感和艺术性。 2、内容要生动有趣 从而更好地吸引参观者。展厅设计师要与客户有良好深入的沟通&#xff0c;搜集与整…

SAP 批量获取BOM中替代料信息(代码分享)

最近用户需要到导出BOM中存在替代料的信息,只要导出替代料的程序,但是使用展开BOM的程序执行后,导致执行时间很长,数量量也非常的大,内存溢出,程序就挂掉了。9万多个物料有BOM,当然不能让用户去导,后面我们写了一段SQL,用内表的方式给用户导出了需要的数据。 同时也找…

10.8k star,超好用的高颜值屏幕录制工具

最近公司需要给新来的同事做一些基础的培训。不过因为时间冲突&#xff0c;没办法现场给大家上课&#xff0c;所以老板让我自己在家把视频课程录制好&#xff0c;还说要让同事们看到我的样子。 这倒是有点费劲了&#xff0c;之前也录制过课程视频&#xff0c;但都是直接用屏幕…

小程序-修改用户头像

1、调用拍照 / 选择图片 // 修改头像 const onAvatarChange () > { // 调用拍照 / 选择图片 uni.chooseMedia({ // 文件个数 count: 1, // 文件类型 mediaType: [image], success: (res) > { console.log(res) // 本地临时文件路径 (本地路径) const { tempFilePath } …

【Tools】SpringBoot工程中,对于时间属性从后端返回到前端的格式问题

Catalog 时间属性格式问题一、需求二、怎么使用 时间属性格式问题 一、需求 对于表中时间字段&#xff0c;后端创建对应的实体类的时间属性需要设定格式&#xff08;默认的格式不方便阅读&#xff09;&#xff0c;再返回给前端。 二、怎么使用 导入jackson相关的坐标&#x…

PostgreSQL事务基础理解

PostgreSQL事务 事务是数据库管理系统执行过程中的一个逻辑单位&#xff0c;由一个有限的数据库操作序列构成。数据库事务通常包含一个序列对数据库的读和写操作&#xff0c;主要是包含以下两个目的&#xff1a; 为数据库操作序列提供一个从失败中恢复到正常状态的方法&#…

vue 打印、自定义打印、页面打印、隐藏页眉页脚

花了一天时间搞了个打印功能&#xff0c;现则将整体实现过程进行整理分享。先来看看效果图&#xff1a; 1、页面展示为&#xff1a; 2、重组页面打印格式为&#xff1a;这里重组页面的原因是客户要求为一行两列打印 &#xff01;内容过于多的行则独占一行显示完整。 整体实现&…

isscc2024 short course2 Performance Compute Environment

这部分分为4部分&#xff1a; 概览&#xff1a;LLMs和生成式AI 探讨大语言模型&#xff08;LLMs&#xff09;和生成式AI的整体环境&#xff0c;及其对硬件加速器设计的影响。 高性能AI加速器的特定考虑因素 广泛的模型和使用案例支持&#xff1a;需要设计能支持多种模型和应…

python中的线程并行

文章目录 1. 单线程2. 线程池ThreadPoolExecutor 1. 单线程 现在有1154张图片需要顺时针旋转后保存到本地&#xff0c;一般使用循环1154次处理&#xff0c;具体代码如下所示&#xff0c;img_paths中存储1154个图片路径&#xff0c;该代码段耗时约用97ms。 t1time.time() for …

SpringCloud系列(30)--准备使用Hystrix的前期工作,创建服务消费者模块

前言&#xff1a;在上一章节中我们创建了服务提供者模块&#xff0c;而本节内容则是创建服务消费者模块。 1、创建一个服务提供者模块&#xff0c;命名为cloud-consumer-feign-hystrix-order80 (1)在父工程下新建模块 (2)选择模块的项目类型为Maven并选择模块要使用的JDK版本 …

面向Prompt编程

Prompt 就像和一个人对话&#xff0c;你说一句&#xff0c;ta 回一句&#xff0c;你再说一句&#xff0c;ta 再回一句…… Prompt 就是你发给大模型的指令&#xff0c;比如「讲个笑话」、「用 Python 编个贪吃蛇游戏」、「给男/女朋友写封情书」等 貌似简单&#xff0c;但意义…

vue项目实战 - 如果高效的实现防抖和节流

在Vue项目中&#xff0c;处理高频事件的优化至关重要&#xff0c;直接影响用户体验和应用性能。防抖&#xff08;Debounce&#xff09;和节流&#xff08;Throttle&#xff09;是两种常用且有效的方法&#xff0c;可以控制事件触发频率&#xff0c;减少不必要的资源消耗。如何在…

labview_开放协议

一、开放协议 二、硬件设置 英格索兰硬件设置&#xff1a; 三、配套测试软件 四、Labview代码

科技赋能,打破视障人士的沟通壁垒

在探索如何增强盲人群体的社会参与度与幸福感的旅程中&#xff0c;盲人社交能力提升策略成为了不容忽视的一环。随着科技的不断进步&#xff0c;像“蝙蝠避障”这样的辅助软件&#xff0c;不仅在日常出行中为盲人提供了实时避障和拍照识别的便利&#xff0c;也在无形中为他们拓…

SQL面试题练习 —— 波峰波谷

来源&#xff1a;字节今日头条 目录 1 题目2 建表语句3 题解 1 题目 有如下数据&#xff0c;记录每天每只股票的收盘价格&#xff0c;请查出每只股票的波峰和波谷的日期和价格&#xff1b; 波峰定义&#xff1a;股票价格高于前一天和后一天价格时为波峰 波谷定义&#xff1a;股…

FPGA状态机设计详解

一.什么是状态机&#xff1f; 想象一下你正在玩一个电子游戏&#xff0c;角色有多种状态&#xff0c;比如“行走”、“跳跃”、“攻击”等。每当你按下不同的按键或者满足某些条件时&#xff0c;角色的状态就会改变&#xff0c;并执行与该状态对应的动作。这就是状态机的一个简…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-23.3,4,5,6 讲 I2C驱动-读取AP3216C传感器​

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

计算机SCI期刊,IF=8+,专业性强,潜力新刊!

一、期刊名称 Journal of Big data 二、期刊简介概况 期刊类型&#xff1a;SCI 学科领域&#xff1a;计算机科学 影响因子&#xff1a;8.1 中科院分区&#xff1a;2区 出版方式&#xff1a;开放出版 版面费&#xff1a;$1990 三、期刊征稿范围 《大数据杂志》发表了关于…