tauri中加载本地文件图片或者下载网络文件图片后存储到本地,然后通过前端页面展示

news2024/9/29 3:23:36

有一个需求是需要将本地上传的文件或者网络下载的文件存储到本地,并展示在前端页面上的。其实如果只是加载本地文件,然后展示还是挺简单的,可以看我的文章:tauri程序加载本地图片或者文件在前端页面展示-CSDN博客

要想实现上述需求,需要三个步骤,配置相应的文件和文件夹访问权限,然后将文件存储到软件的相应目录中,再从目录中加载这个资源并展示。

配置访问权限

如果你需要通过弹窗选择加载本地文件,需要配置dialog权限,存储文件需要配置存储目录权限fs下面的scope和path权限,想要加载文件并在前端页面可以访问,需要配置资产协议访问权限protocol。其中scope是你要存储文件到哪个路径下,assetScope是你要访问哪些路径下的资源。

            "path": {
                "all": true
            },
            "fs": {
                "all": true,
                "readFile": true,
                "writeFile": true,
                "readDir": true,
                "copyFile": true,
                "createDir": true,
                "removeDir": true,
                "removeFile": true,
                "renameFile": true,
                "exists": true,
                "scope": ["$CACHE/PakePlus/*", "$APPDATA/*"]
            },
            "dialog": {
                "all": true,
                "ask": true,
                "confirm": true,
                "message": true,
                "open": true,
                "save": true
            },
            "protocol": {
                "all": true,
                "asset": true,
                "assetScope": ["$PICTURE", "$CACHE/*"]
            },

存储文件到本地

加载本地文件并存储到软件指定的文件夹中,这里需要读取到文件的内容,如果是图片文件,需要读为二进制内容,并进行存储。

import { writeBinaryFile, BaseDirectory } from '@tauri-apps/api/fs';
import { appDataDir } from '@tauri-apps/api/path';

const saveImageToAppData = async (filePath) => {
  // 读取原始图片文件
  const response = await fetch(filePath);
  const imageBlob = await response.blob();
  const imageArrayBuffer = await imageBlob.arrayBuffer();
  const imageData = new Uint8Array(imageArrayBuffer);

  // 获取应用数据目录
  const appDataDirPath = await appDataDir();

  // 拼接文件保存路径
  const fileName = filePath.split('/').pop();  // 获取原始文件名
  const savePath = `${appDataDirPath}/${fileName}`;

  // 将图片保存到应用数据目录
  await writeBinaryFile(savePath, imageData, { dir: BaseDirectory.AppData });

  console.log(`Image saved to: ${savePath}`);
  return savePath;
}

或者使用前端的input标签选中文件拿到base64编码的文件,然后转为ArrayBuffer再进行存储:

        <input
            id="open"
            type="file"
            name="filename"
            style="display: none"
            @change="changeFile"
        />



// iconInput change
const changeFile = (event: any) => {
    // get base64 content
    const file = event.target.files[0] // 获取文件
    console.log('file---', file)
    if (file) {
        appForm.icon = file.name
        console.log('file---', event.target.files)
        // appForm.icon = event.target.files.name
        const reader = new FileReader() // 创建FileReader对象
        reader.onload = function (e: any) {
            const base64String = e.target.result.split('base64,')[1] // 获取Base64编码
            console.log('base64String---', base64String) // 打印Base64编码内容
            // save image to datadir
            saveImage(file.name, base64String)
        }
        reader.readAsDataURL(file) // 将文件读取为Base64
    }
}



// save image file to datadir
const saveImage = async (fileName: string, base64: string) => {
    // base64 to arraybuffer
    const imageArrayBuffer = base64ToArrayBuffer(base64)
    // save file
    const imageData = new Uint8Array(imageArrayBuffer)
    // 获取应用数据目录
    const appDataPath = await resourceDir()
    console.log('appDataPath------', appDataPath)
    // 拼接文件保存路径
    const savePath = `${appDataPath}${fileName}`
    // 将图片保存到应用数据目录
    await writeBinaryFile(savePath, imageData, {
        dir: BaseDirectory.Cache,
    })
    console.log(`Image saved to: ${savePath}`)
    appForm.desc = savePath
    const filePath = await join(appDataPath, fileName)
    console.log('filePath---', filePath)
    const assetUrl = convertFileSrc(filePath)
    console.log('assetUrl---', assetUrl)
    localImagePath.value = assetUrl
}

// 将base64转换为ArrayBuffer
const base64ToArrayBuffer = (base64: string) => {
    // 创建一个新的 ArrayBuffer
    const binaryString = atob(base64)
    const len = binaryString.length
    const arrayBuffer = new ArrayBuffer(len)
    const uint8Array = new Uint8Array(arrayBuffer)
    // 将二进制字符串中的字符逐个存入 Uint8Array
    for (let i = 0; i < len; i++) {
        uint8Array[i] = binaryString.charCodeAt(i)
    }
    return arrayBuffer
}

加载文件为Url

读取保存的文件内容,并展示到页面上,需要拿到存储的路径,然后通过convertFileSrc这个api将文件路径转化为前端可以直接访问的文件:

    const filePath = await join(appDataPath, fileName)
    console.log('filePath---', filePath)
    const assetUrl = convertFileSrc(filePath)
    console.log('assetUrl---', assetUrl)
    localImagePath.value = assetUrl

如果是图片文件,直接将url设置进去就可以了。

报错解决

1.Unhandled Promise Rejection: The `Path` module is not enabled. You must enable one of its APIs in the allowlist.

这是因为没有开启path路径访问权限:

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

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

相关文章

【Linux】项目自动化构建工具-make/Makefile 详解

&#x1f525; 个人主页&#xff1a;大耳朵土土垚 &#x1f525; 所属专栏&#xff1a;Linux系统编程 这里将会不定期更新有关Linux的内容&#xff0c;欢迎大家点赞&#xff0c;收藏&#xff0c;评论&#x1f973;&#x1f973;&#x1f389;&#x1f389;&#x1f389; 文章目…

关于车载视频监控的重要性及其发展趋势

一、车载视频监控的意义和概念 车载视频监控是专为车载安防领域打造的一款新型视频监控设备。随着社会的快速发展和科技的不断进步&#xff0c;安装车载视频监控设备已经成为社会发展的必然趋势。车载视频监控不仅关乎个人安全&#xff0c;更对企业的安全生产和管理起着至关重要…

可编辑PPT | 能源企业数字化框架、数字化运营及数字化平台建设方案

项目背景及需求理解 首先提出了全球能源互联网的概念&#xff0c;强调了清洁能源和电能替代的重要性&#xff0c;并介绍了德国工业4.0战略以及泛在电力物联网的创新。文档探讨了信息化与工业化的深度融合&#xff0c;以及云计算、大数据、物联网和移动应用等新技术在能源行业的…

克隆GitHub仓库中的一个文件夹

要只克隆GitHub仓库中的一个文件夹&#xff0c;你可以使用 git sparse-checkout 功能。以下是具体步骤&#xff1a; 克隆仓库&#xff08;使用 --no-checkout 选项&#xff0c;避免下载所有内容&#xff09;&#xff1a; git clone --no-checkout <仓库地址> 进入克隆的…

微信小程序组件封装使用

1.第一步先新建一个components组件的文件夹第二步在创建一个文件夹第三步在新建components 例如先封装一个VCaption头部导航组件

IvorySQL 3.4 来了

9 月 26 日&#xff0c;IvorySQL 3.4 发版。本文将带大家快速了解新版本特性。 IvorySQL 3.4 发版说明 IvorySQL 3.4 基于 PostgreSQL 16.4&#xff0c;修复了多个问题&#xff0c;并增强多项功能。 PostgreSQL 16.4 的变更 在未经授权时防止 pg_dump 执行&#xff0c;并引入一…

初识C语言(三)

感兴趣的朋友们可以留个关注&#xff0c;我们共同交流&#xff0c;相互促进学习。 文章目录 前言 八、函数 九、数组 &#xff08;1&#xff09;数组的定义 &#xff08;2&#xff09;数组的下标和使用 十、操作符 &#xff08;1&#xff09;算数操作符 &#xff08;2&#xff…

MySQL多版本并发控制MVCC实现原理

MVCC MVCC 是多版本并发控制方法&#xff0c;用来解决读和写之间的冲突&#xff0c;比如脏读、不可重复读问题&#xff0c;MVCC主要针对读操作做限制&#xff0c;保证每次读取到的数据都是本次读取之前的已经提交事务所修改的。 概述 当一个事务要对数据库中的数据进行selec…

AIGAME背后的强大背景与AI币价值的崛起

AIGAME平台背后汇集了强大的资本和技术支持&#xff0c;凭借蒙特加密产业基金的战略投资和汇旺集团的多元化Web3基础设施建设&#xff0c;AIGAME在全球范围内迅速崛起。平台所使用的Sleepless AI技术&#xff0c;结合区块链与AI的深度融合&#xff0c;赋能AI币&#xff0c;使其…

【hot100-java】【二叉树的直径】

R9-二叉树篇 左子树的深度右子树的深度即可 但好像不行 思路&#xff1a; 对于每个节点&#xff0c;计算它的左子树深度和右子树深度相加的和&#xff0c;并更新最大值。 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode le…

海外社媒怎么运营?代理IP有必要吗?看这5个关键点就够了!

想要在海外社交媒体上大放异彩&#xff0c;但不知从何下手&#xff1f; 面对着Instagram、Facebook、Twitter等平台的海量用户&#xff0c;如何确保你的品牌能够脱颖而出&#xff1f; 如何在海外社交媒体上突破地域限制&#xff0c;实现全球覆盖&#xff1f; 别担心&#xf…

3D建模软件 | Blender v4.2.2 绿色版

Blender是一款功能强大的免费开源3D创作套件&#xff0c;适用于创建3D可视化效果&#xff0c;如静态图像、3D动画、视觉特效以及视频编辑。Blender以其跨平台兼容性、高效内存管理、统一的工作流程和活跃的社区支持而受到独立艺术家和小型工作室的青睐。 它提供了从建模、渲染…

AI爆火的今天,普通人如何利用AI赚钱?

AI是一门非常有前景和潜力的领域&#xff0c;而且赚钱也并非难事&#xff0c;可以说只是一层窗户纸的问题。我身边就有两个朋友&#xff0c;他们通过AI副业获得的收入甚至超过了他们的主要工作收入。更令人惊讶的是&#xff0c;学会AI并开始创造收入并不需要太多的技术背景&…

vue初学随笔

Vue基础 Vue基本概念 Vue是什么 Vue是一个渐进式的JavaScript框架&#xff0c;它基于标准 HTML、CSS 和 JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助你高效地开发用户界面。 渐进式&#xff1a;各个特性可以根据项目需要逐渐引入和…

运算符两边的数据类型

6-3 类型转换 1.非赋值运算的类型转换 &#xff08;1&#xff09;水平方向的转换&#xff1a;所有的char型和short型自动地转换成int 型&#xff0c;所有的unsigned short 型自动地转换成unsigned型&#xff0c;所有的long型自动地转换成unsigned long 型&#xff0c;所有的f…

蓝桥等级考试C++组七级真题-2022-04-23

PDF及答案回复:LQDKC720220423 单项选择题 1、C L7 (15分) 执行以下程序后&#xff0c;输出结果是( )。 int a5; int b a; cout << a << " "<< b;A 5 5 B 5 6 C 6 5 D 6 6 2、CL7(15分) 执行以下程序后&#xff0c;输出结果是() int k0; for(…

SLM2304S 600V, 130mA/270mA 高压半桥驱动芯片,隐藏着哪些强大功能?

SLM2304SCA-13GTR是一款高压、高速的功率MOSFET和IGBT驱动器&#xff0c;它提供相互依存的高边、低边输出驱动信号。采用专有的高压集成电路和锁存免疫CMOS技术&#xff0c;提供可靠的单芯片驱动方案。 逻辑输入电平与标准CMOS或LSTTL输出兼容&#xff0c;最低支持3.3V逻辑。输…

队列的基本概念以及模拟使用

1.队列的概念&#xff1a; 只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的线性表&#xff0c;队列具有先进先出FIFO 入队列 :进行插入操作的一端称为队尾. 出队列:进行删除操作的一端称为队头。 图例如下&#xff1a; 2.Queue是一个接口&…

Select插件的用法

文章目录 1.知识回顾2.使用方法2.1 builder属性2.2 selector属性2.3 shouldRebuild属性2.4 child属性3 示例代码我们在上一章回中介绍了组件之间共享数据相关的内容,本章回中将继续介绍该内容.闲话休提,让我们一起Talk Flutter吧。 1.知识回顾 我们在前面章回中介绍了全局共…

Ubuntu 开机自启动 .py / .sh 脚本,可通过脚本启动 roslaunch/roscore等

前言 项目中要求上电自启动定位程序&#xff0c;所以摸索了一种 Ubuntu 系统下开机自启动的方法&#xff0c;开机自启动 .sh 脚本&#xff0c;加载 ROS 环境的同时启动 .py 脚本。在 . py 脚本中启动一系列 ROS 节点。 一、 .sh 脚本的编写 #!/bin/bash # gnome-terminal -- …