使用electron属性实现保存图片并获取图片的磁盘路径

在普通的网页开发中,JavaScript由于安全性的考虑,通常是无法直接获取到客户端的磁盘路径的。浏览器出于隐私和安全原因对此类信息进行了限制。

在浏览器环境下,JavaScript主要通过Web APIs来与浏览器进行交互,而这些API通常受到浏览器的安全策略的限制。文件系统信息是被认为是敏感的信息,因此浏览器不提供直接访问客户端磁盘路径的API。所以要使用electron属性来获取。

第一步:

electron分为主进程和渲染进程,主进程就是使用electron的特性属性api,渲染进程就是我们的代码,比如vue页面代码这种。

首先我们要把项目用electron启动起来,具体怎么启动看我上一篇博客

启动完成后,找到项目文件中的backgroun.js文件,这是electron主进程的文件

把以下代码加进去

import { app, protocol, BrowserWindow ,ipcMain,ipcRenderer,dialog} from 'electron'
const fs = require('fs');
app.on('ready', async () => {// if (isDevelopment && !process.env.IS_TEST) {//   // Install Vue Devtools//   try {//     await installExtension(VUEJS_DEVTOOLS)//   } catch (e) {//     console.error('Vue Devtools failed to install:', e.toString())//   }// }createWindow()// 新增:在主进程中处理打开保存图片对话框的请求ipcMain.handle('dialog:saveImage', async (event, dataURL) => {return saveImage(dataURL);});
})// 将保存图片的逻辑封装成一个函数
async function saveImage(dataURL) {let base64 = dataURL.replace(/^data:image\/\w+;base64,/, '');let dataBuffer = Buffer.from(base64, 'base64');const options = {title: 'Save Image',buttonLabel: '保存', // 自定义保存按钮的文字defaultPath: 'image.jpg', // 默认文件名filters: [{ name: 'Images', extensions: ['jpg', 'png', 'gif'] }]};const { canceled, filePath } = await dialog.showSaveDialog(options);if (canceled) {return null; // 用户取消保存文件时返回 null} else {// 将 dataURL 保存到 filePath 的逻辑代码fs.writeFile(filePath, dataBuffer, function (err) {if (err) {console.error(err, '保存失败');} else {console.log(filePath, '保存成功');}});return filePath; // 返回用户选择的文件路径}
}
  1. 在 Electron 应用程序启动后,创建了窗口(createWindow函数应该是在代码中其他位置定义的)。
  2. 通过 ipcMain.handle 方法,为名为 'dialog:saveImage' 的事件注册了一个处理函数,用于处理保存图片对话框的请求。当渲染进程发送 'dialog:saveImage' 事件时,主进程将会执行 saveImage 函数。
  3. saveImage 函数封装了保存图片的逻辑。首先将 Data URL 转换为 Buffer 格式,然后通过 dialog.showSaveDialog 方法展示保存对话框,用户选择保存路径后,将图片文件保存到指定路径。
  4. saveImage 函数中:

  5. 首先通过 dataURL.replace 和 Buffer.from 将 Data URL 转换成了 Buffer 格式。
  6. 然后使用 dialog.showSaveDialog 方法展示保存对话框,用户选择保存路径后,通过 fs.writeFile 方法将 Buffer 写入文件。
  7. 最后根据保存成功或失败,返回相应的结果给渲染进程。

fs 是 Node.js 核心模块中的一个模块,全称为 File System(文件系统)。这个模块提供了一系列用于处理文件和文件系统的方法,可以用于读取文件、写入文件、创建目录、删除文件等操作。通过 fs 模块,你可以在 Node.js 程序中对文件和文件系统进行各种操作,包括读写文件、文件夹的操作等。

在 Electron 应用程序中,由于可以利用 Node.js 的能力,因此可以在主进程中使用 fs 模块来处理文件和文件系统相关的操作,比如在上面的代码中就使用了 fs.writeFile 方法来将图片保存到指定路径。

这是最终background.js文件的代码:

'use strict'import { app, protocol, BrowserWindow ,ipcMain,ipcRenderer,dialog} from 'electron'
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'
// import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'
const isDevelopment = process.env.NODE_ENV !== 'production'
const fs = require('fs');// Scheme must be registered before the app is ready
protocol.registerSchemesAsPrivileged([{ scheme: 'app', privileges: { secure: true, standard: true } }
])async function createWindow() {// Create the browser window.const win = new BrowserWindow({width: 800,height: 600,webPreferences: {// Use pluginOptions.nodeIntegration, leave this alone// See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more infonodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION}})win.maximize()if (process.env.WEBPACK_DEV_SERVER_URL) {// Load the url of the dev server if in development modeawait win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)if (!process.env.IS_TEST) win.webContents.openDevTools()} else {createProtocol('app')// Load the index.html when not in developmentwin.loadURL('app://./index.html')}
}// Quit when all windows are closed.
app.on('window-all-closed', () => {// On macOS it is common for applications and their menu bar// to stay active until the user quits explicitly with Cmd + Qif (process.platform !== 'darwin') {app.quit()}
})app.on('activate', () => {// On macOS it's common to re-create a window in the app when the// dock icon is clicked and there are no other windows open.if (BrowserWindow.getAllWindows().length === 0) createWindow()
})// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', async () => {// if (isDevelopment && !process.env.IS_TEST) {//   // Install Vue Devtools//   try {//     await installExtension(VUEJS_DEVTOOLS)//   } catch (e) {//     console.error('Vue Devtools failed to install:', e.toString())//   }// }createWindow()// 新增:在主进程中处理打开保存图片对话框的请求ipcMain.handle('dialog:saveImage', async (event, dataURL) => {return saveImage(dataURL);});
})// Exit cleanly on request from parent process in development mode.
if (isDevelopment) {if (process.platform === 'win32') {process.on('message', (data) => {if (data === 'graceful-exit') {app.quit()}})} else {process.on('SIGTERM', () => {app.quit()})}
}// 将保存图片的逻辑封装成一个函数
async function saveImage(dataURL) {let base64 = dataURL.replace(/^data:image\/\w+;base64,/, '');let dataBuffer = Buffer.from(base64, 'base64');const options = {title: 'Save Image',buttonLabel: '保存', // 自定义保存按钮的文字defaultPath: 'image.jpg', // 默认文件名filters: [{ name: 'Images', extensions: ['jpg', 'png', 'gif'] }]};const { canceled, filePath } = await dialog.showSaveDialog(options);if (canceled) {return null; // 用户取消保存文件时返回 null} else {// 将 dataURL 保存到 filePath 的逻辑代码fs.writeFile(filePath, dataBuffer, function (err) {if (err) {console.error(err, '保存失败');} else {console.log(filePath, '保存成功');}});return filePath; // 返回用户选择的文件路径}
}

第二步:

去渲染进程里写相关代码,也就是你的.vue文件

   //保存画布图片saveCanvasBackground() {if (this.image.url == '') return// 获取 canvas 元素和 Fabric 对象const canvas = document.getElementById("label-canvas");const fabricObj = this.fabricObj;// 将 canvas 内容保存为图片数据 URLconst dataURL = canvas.toDataURL({format: "png", // 保存的图片格式quality: 0.8, // 图片质量});//想主进程发送打开保存图片选项框请求ipcRenderer.invoke('dialog:saveImage', dataURL).then(response => {console.log(response, 'sssss');if (response) {// 接口// setsaveImage({//   img:response// }).then(res=>{//   console.log(res,'保存成功接口');// }).catch(err=>{//   console.log(err,'保存失败接口');// })} else {//用户取消}}).catch(err => {console.error(err);});// 创建一个 Blob 对象// const byteCharacters = atob(dataURL.split(",")[1]);// const byteNumbers = new Array(byteCharacters.length);// for (let i = 0; i < byteCharacters.length; i++) {//   byteNumbers[i] = byteCharacters.charCodeAt(i);// }// const byteArray = new Uint8Array(byteNumbers);// const blob = new Blob([byteArray], { type: "image/png" });// // 创建一个下载链接// const url = URL.createObjectURL(blob);// // 创建一个下载按钮并触发点击// const a = document.createElement("a");// a.style.display = "none";// a.href = url;// a.download = "saved_image.png"; // 设置下载的文件名// document.body.appendChild(a);// a.click();// // 释放对象 URL,避免内存泄漏// window.URL.revokeObjectURL(url);},

这段代码是在渲染进程中使用 ipcRenderer.invoke 方法向主进程发送了一个名为 'dialog:saveImage' 的请求,同时传递了一个名为 dataURL 的参数。当主进程处理完这个请求后,渲染进程会接收到相应的结果。

在这段代码中,使用了 ipcRenderer.invoke 方法来发送请求,并通过 Promise 对象处理响应。如果主进程成功处理了请求并返回了结果,会执行 then 中的代码,如果出现错误,会执行 catch 中的代码。

then 中的代码中,首先会打印出返回的 response,然后根据返回的结果进行相应的处理。如果 response 存在,表示图片保存成功,可以处理接口请求或其他逻辑;如果 response 不存在,表示用户取消了保存操作,可以做出相应的反应。

整体来说,这段代码的作用是在渲染进程中向主进程发送保存图片选项框的请求,并根据主进程返回的结果进行相应的处理。

以上红色框内就是运行过后获取出来当前保存图片的磁盘路径!

双击点赞!!!! 

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

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

相关文章

【北亚服务器数据恢复】ZFS文件系统服务器ZPOOL下线的数据恢复案例

服务器数据恢复环境&#xff1a; 服务器中有32块硬盘&#xff0c;组建了3组RAIDZ&#xff0c;部分磁盘作为热备盘。zfs文件系统。 服务器故障&#xff1a; 服务器运行中突然崩溃&#xff0c;排除断电、进水、异常操作等外部因素。工作人员将服务器重启后发现无法进入操作系统。…

IPD-PDP产品开发流程-PDT产品开发计划Charter文档模板(word)2

书接上回&#xff0c;继续为大家分享PDT的产品开发计划Charter模板的主要内容。 据华研荟了解&#xff0c;大部分国内的企业在推行IPD的时候就直接像华为一样&#xff0c;把开发计划&#xff08;任务书&#xff09;叫做Charter&#xff0c;而不翻译为中文。其实这也是一种很好…

水果软件2024FL Studio21.3mac苹果中文版

FL STUDIO21发布&#xff0c;提供您一直在等待的出色工作流程功能。通过新效果、多个播放列表曲目选择和无所畏惧的撤消一切编辑&#xff0c;将您的音乐带入2024年。FL Studio21中文完整版是一个功能齐全、开放式架构的PC音乐创作和制作环境。它具有基于音乐音序器的图形用户界…

STL——list容器

目录 1.list基本概念 2.list构造函数 3.list赋值和交换 4.list大小操作 5.list插入和删除 6.list数据存取 7.list反转和排序 8.排序案例 1.list基本概念 功能&#xff1a;将数据进行链式存储。 链表&#xff08;list&#xff09;是一种物理存储单元上非连续的存储结构&…

StringBuilder、StringBuffer

StringBuilder StringBuilder代表可变字符串对象&#xff0c;相当于是一个容器&#xff0c;它里面装的字符串是可以改变的&#xff0c;就是用来操作字符串的。好处&#xff1a;StringBuilder比String更适合做字符串的修该操作&#xff0c;效率会更高&#xff0c;代码也会更简洁…

计算机网络概述(上)——“计算机网络”

各位CSDN的uu们好呀&#xff0c;好久没有更新小雅兰的计算机网络的专栏啦&#xff0c;而且期末考试也要考计算机网络&#xff0c;所以&#xff0c;小雅兰就来写计算机网络的内容啦&#xff01;&#xff01;&#xff01;下面&#xff0c;让我们进入计算机网络概述的世界吧&#…

rust中的超时处理

rust中的超时处理 自从 tokio 1.0发布以来&#xff0c;rust的异步开发总算大势已定。尽管没达到标准库的速度&#xff0c;依然挡不住大家的热情。看编程排行榜&#xff0c;增加2倍的开发者。 既生瑜何生亮&#xff0c;感觉go就是小号的rust。 不废话了。背景&#xff1a;之前…

HarmonyOS引导页登陆页以及tabbar的代码说明 登陆页2

代码&#xff1a;这里的prompt.showToast是弹出提示&#xff0c;Extend(TextInput) 的功能是对TextInput做了公用的样式。isShowProgress是用来控制isShowProgress&#xff0c;出来一个等待效果 import prompt from ‘ohos.promptAction’; import router from ‘ohos.router…

Redis缓存雪崩、缓存击穿、缓存穿透

1. 什么是缓存雪崩 当我们提到缓存系统中的问题&#xff0c;缓存雪崩是一个经常被讨论的话题。缓存雪崩是指在某一时刻发生大量的缓存失效&#xff0c;导致瞬间大量的请求直接打到了数据库&#xff0c;可能会导致数据库瞬间压力过大甚至宕机。尤其在高并发的系统中&#xff0c;…

【iptables】增加规则和删除规则

我们在另外一台机器上&#xff0c;使用ping命令&#xff0c;向当前机器发送报文&#xff0c;如下图所示&#xff0c;ping命令可以得到回应&#xff0c;证明ping命令发送的报文已经正常的发送到了防火墙所在的主机&#xff0c;ping命令所在机器IP地址为31.133&#xff08;黑色&a…

如何解决mac无法访问github

确定github能访问的ip地址 点击检测按钮&#xff0c;找到比较快的ip 修改hosts文件&#xff1a;打开终端&#xff0c;输入 open /etc/hosts 后回车&#xff0c;打开mac的文本编辑器 add github.com 140.82.121.4 github.com 199.232.69.194 github.global.ssl.fastly.net …

微服务与人工智能技术的融合

随着人工智能技术的快速发展&#xff0c;越来越多的企业开始关注微服务架构与人工智能技术的结合&#xff0c;以期在市场竞争中获得更大的优势。本文将深入探讨微服务架构与人工智能技术融合的优势、挑战&#xff0c;以及实现这一融合的最佳实践和方法。 首先&#xff0c;让我们…

NCNN环境部署及yolov5pt转ncnn模型转换推理

该内容还未完整&#xff0c;笔记内容&#xff0c;持续补充。 〇开发环境版本 vs2022 cmake3.21.1 ncnn20231027发行版 yolov5s v6.2 vunlkan1.2.198.1 Protobuf3.20.0 Opencv3.4.1 一、模型转换 yolov5s v6.2训练的pt模型&#xff0c;直接导出tourchscript&#xff0c…

ubuntu 开机自报IP地址(用于无屏幕小车-远程连接)

目录 1.环境安装2.代码3.打包成可执行文件4.开启开机自启 1.环境安装 sudo apt-get install espeak #先安装这个库 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyttsx32.90 #再安装pyttsx3 pyinstaller pip install -i https://pypi.tuna.tsinghua.edu.cn/si…

C语言实例_生成6位数的随机密码

一、前言 随着数字化时代的到来&#xff0c;人们在各个方面需要使用密码来保护个人隐私和敏感信息的安全。为了确保密码的安全性&#xff0c;密码应该是足够强大和难以猜测的&#xff0c;这就需要密码生成器来帮助用户生成高强度的随机密码。 随机密码生成器是一种计算机程序…

P1019 [NOIP2000 提高组] 单词接龙 刷题笔记

P1019 [NOIP2000 提高组] 单词接龙 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 思路来自 大佬 Chardo 的个人中心 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 匹配 &#xff1a; 将 第一个字符串末尾 和第二个字符串第一个开始匹配 如果 j<i这段走完了 flag还没…

ffmpeg两种windows版本区别说明

版本一 必须拷贝exe和dll文件才能使用&#xff0c;如果缺少dll则exe不正正常执行 如果缺少dll &#xff0c;执行 exe会报错如下 版本2 直接拷贝exe就能使用&#xff0c;没有依赖的环境

Power BI - 5分钟学习合并文件

每天5分钟&#xff0c;今天介绍Power BI合并文件 什么是合并文件&#xff1f; 合并文件就是将具有相同架构的多个文件合并到单个逻辑表中。 如果要合并同一文件夹中的所有文件时&#xff0c;此功能非常有用。 例如&#xff0c;如果你有一个文件夹&#xff0c;其中包含公司的所…

极智嘉加快出海发展步伐,可靠产品方案获客户认可

2023年&#xff0c;国内本土企业加快出海征程&#xff0c;不少企业在出海发展中表现出了优越的集团实力与创新的产品优势&#xff0c;有力彰显了我国先进的科技研发实力。作为全球仓储机器人引领者&#xff0c;极智嘉&#xff08;Geek&#xff09;也在不断加快出海发展步伐&…

已囤积189150枚BTC,微策略的策略会暴雷吗?

号外&#xff1a;教链内参12.27《美元快速下行&#xff0c;黄金再创新高》 日前&#xff0c;微策略&#xff08;Microstrategy&#xff09;创始人Michael Saylor发推称&#xff0c;微策略再次出手&#xff0c;以均价约42110刀再次加仓14620枚BTC。截至2023.12.26&#xff0c;微…