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.pswp.cn/bicheng/15057.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/15057.shtml
英文地址,請注明出處:http://en.pswp.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關于如何查找想…