uni-app 经验分享,从入门到离职(实战篇)——模拟从后台获取图片路径数据后授权相册以及保存图片到本地(手机相册)

文章目录

  • 📋前言
    • ⏬关于专栏
  • 🎯需求描述
  • 🎯前置知识点
    • 🧩uni.showLoading()
    • 🧩uni.authorize()
    • 🧩uni.downloadFile()
    • 🧩uni.saveImageToPhotosAlbum()
  • 🎯演示代码
    • 🧩关于图片接口
    • 🧩代码解析简述
  • 📝最后


在这里插入图片描述

📋前言

这篇文章是本专栏 uni-app 的项目实战篇,主要内容的是模拟前端通过调用接口,然后获取到数据图片的路径数据,然后授权相册,最后把图片保存到本地(相册)。

⏬关于专栏

本专栏主要是分享和介绍从零到一学习和使用的 uni-app 的笔记和个人经验。通过个人的学习经验和工作经验来给大家分享关于 uni-app 开发的技巧,以及快速入门的诀窍等等。

专栏主页:uni-app_黛琳ghz的博客-CSDN博客


🎯需求描述

案例场景:用户通过点击某个按钮可以把图片保存到相册,比如说含有二维码的名片图片、海报图片等等。

需求分析:这里以分享海报的需求为例子,用户点击分享海报,然后后台生成含二维码、海报内容的图片,前端通过调用此接口获取到图片的路径信息(路径后端拼接好返回),然后用户点击按钮,然后先授权相册,最后再保存图片到相册。(可以参考下图的原型图,仅供参考)
在这里插入图片描述


🎯前置知识点

在编写代码之前,我们先熟悉一下本次实战所需用到的一些知识点和 uni-app 的内置 API。

🧩uni.showLoading()

uni.showLoading() 是 uni-app 框架提供的一个 API ,用于显示加载提示框。它的作用是在页面上展示一个加载中的提示框,告知用户当前正在进行一些耗时的操作,比如加载数据或进行网络请求。

uni.showLoading() 方法接受一个对象参数,可以包含以下属性:

  • title(可选):加载提示框的标题文本,默认为"加载中"。
  • mask(可选):是否显示透明蒙层,防止用户在加载过程中进行其他操作,默认值为true,表示显示蒙层。

调用 uni.showLoading() 方法后,加载提示框会显示在页面上,直到调用uni.hideLoading() 方法或者一段时间后自动消失。示例代码:

uni.showLoading({
  title: '加载中',
  mask: true
});

在上述示例中,uni.showLoading() 方法被调用,显示一个标题为"加载中"的加载提示框,并且显示透明蒙层。当加载完成后,应该调用 uni.hideLoading() 来隐藏加载提示框。


🧩uni.authorize()

uni.authorize() 是 uni-app 框架提供的一个 API ,用于请求用户授权。它的作用是向用户申请获得指定的授权权限,比如获取用户的地理位置、相机、相册等权限。

uni.authorize() 方法接受一个对象参数,可以包含以下属性:

  • scope:要申请的授权权限的标识符。不同的授权权限有不同的标识符,例如获取用户信息的标识符为 scope.userInfo,获取用户相册的标识符为 scope.writePhotosAlbum。
  • success(可选):授权成功时执行的回调函数。
  • fail(可选):授权失败时执行的回调函数。

在调用 uni.authorize() 方法时,会向用户展示一个授权对话框,询问用户是否允许获取指定的权限。如果用户同意授权,则执行 success 回调函数;如果用户拒绝授权或授权失败,则执行 fail 回调函数。示例代码:

uni.authorize({
  scope: 'scope.writePhotosAlbum',
  success: () => {
    // 授权成功时的操作
    // 可以在这里进行保存图片等操作
  },
  fail: () => {
    // 授权失败时的操作
    // 可以给用户提示授权失败的信息
  }
});

在上述示例中,uni.authorize() 方法被调用,申请获取写入用户相册的权限。如果用户同意授权,则执行 success 回调函数;如果用户拒绝授权或授权失败,则执行 fail 回调函数。通常在 success 回调函数中进行后续的操作,比如保存图片到相册等操作。


🧩uni.downloadFile()

uni.downloadFile() 是 uni-app 框架提供的一个API,用于下载文件。它的作用是通过网络请求下载文件,可以是图片、音频、视频等内容。

uni.downloadFile() 方法接受一个对象参数,可以包含以下属性:

  • url:要下载的文件的远程地址。
  • success(可选):文件下载成功时执行的回调函数,回调函数的参数中包含了本地临时文件路径 tempFilePath。
  • fail(可选):文件下载失败时执行的回调函数。

在调用 uni.downloadFile() 方法时,uni-app 将发送请求去下载指定的文件,并将文件保存在本地临时路径中。如果文件下载成功,则执行 success 回调函数并传递本地临时文件路径作为参数;如果文件下载失败,则执行 fail 回调函数。示例代码:

uni.downloadFile({
  url: 'https://example.com/image.jpg',
  success: res => {
    // 文件下载成功时的操作
    // 可以使用 res.tempFilePath 获取本地临时文件路径
  },
  fail: err => {
    // 文件下载失败时的操作
    // 可以给用户提示下载失败的信息
  }
});

在上述示例中,uni.downloadFile() 方法被调用以下载名为 “image.jpg” 的图片文件。如果文件下载成功,则执行 success 回调函数并使用 res.tempFilePath 获取本地临时文件的路径;如果文件下载失败,则执行 fail 回调函数。你可以根据需求在 success 回调函数中进行后续的操作,比如将文件显示在页面上或保存到相册等。


🧩uni.saveImageToPhotosAlbum()

uni.saveImageToPhotosAlbum() 是 uni-app 框架提供的一个API,用于将图片保存到用户的相册。它的作用是将指定路径的图片保存到用户的相册中。

uni.saveImageToPhotosAlbum() 方法接受一个对象参数,可以包含以下属性:

  • filePath:要保存到相册的图片文件路径。
  • success(可选):保存成功时执行的回调函数。
  • fail(可选):保存失败时执行的回调函数。

在调用 uni.saveImageToPhotosAlbum() 方法时,uni-app 将尝试将指定路径的图片保存到用户的相册中。如果保存成功,则执行 success 回调函数;如果保存失败,则执行 fail 回调函数。示例代码:

uni.saveImageToPhotosAlbum({
  filePath: 'path/to/image.jpg',
  success: () => {
    // 保存成功时的操作
    // 可以给用户提示保存成功的信息
  },
  fail: () => {
    // 保存失败时的操作
    // 可以给用户提示保存失败的信息
  }
});

在上述示例中,uni.saveImageToPhotosAlbum() 方法被调用以将指定路径的 “image.jpg” 图片保存到用户的相册中。如果保存成功,则执行 success 回调函数;如果保存失败,则执行 fail 回调函数。你可以根据需求在回调函数中给用户提示保存成功或失败的信息。请确保传入的 filePath 参数是正确的本地文件路径。


🎯演示代码

这个演示代码延用之前项目 (具体看该专栏的文章《uni-app 经验分享,从入门到离职(二)—— tabBar 底部导航栏实战基础篇》) 的代码页面,如下图是简单的操作流程,以及简单的演示页面。流程为点击绿色的按钮,然后出现加载中提示框,然后出现授权相册的提示框,允许授权后,弹出另存为图片的窗口表示图片可以下载了,最后点击保存即可。
在这里插入图片描述
下面是该项目页面的完整代码。

<template>
	<view class="downloadbtn" @click="downloadimg">
		点击下载图片
	</view>
</template>

<script>
	export default {
		data() {
			return {
				img: ''
			}
		},
		onLoad() {

		},
		methods: {
			downloadimg() {
				uni.showLoading({
					title: '加载中',
					mask: true,
				});
				uni.request({
					url: 'http://127.0.0.1:3000/getImage',
					method: 'GET',
					header: {
						'Content-Type': 'application/x-www-form-urlencoded',
					},
					success: res => {
						// 请求成功时的操作
						// console.log(res.data); // 打印返回的数据
						console.log(res)
						this.img = res.data.imagePath
						this.saveToAlbum(this.img)
					},
					fail: err => {
						// 请求失败时的操作
						console.error(err);
					}
				});
			},
			saveToAlbum(url) {
				uni.authorize({
					scope: 'scope.writePhotosAlbum',
					success: () => {
						// 在授权成功后执行保存图片的操作
						this.saveImage(url);
					},
					fail: () => {
						uni.hideLoading()
						uni.showModal({
							// title: '授权失败,请前往设置页授权',
							title: '授权失败',
							// icon: 'none',
							content: '请前往设置页手动授权该权限',
							showCancel: false,
							confirmText: '去设置',
							success: res => {
								if (res.confirm) {
									// 用户点击确定,跳转到设置页
									uni.openSetting({
										success: () => {
											// 设置页打开成功后的操作
											uni.hideLoading()
										}
									});
								}
							}
						});
					}
				});
			},
			saveImage(url) {
				uni.downloadFile({
					url: url,
					success: (res) => {
						console.log(res)
						// if (res.statusCode === 200) {
						uni.saveImageToPhotosAlbum({
							filePath: res.tempFilePath,
							success: () => {
								uni.showToast({
									title: '保存成功',
									icon: 'success'
								});
							},
							fail: () => {
								uni.showToast({
									title: '保存失败',
									icon: 'none'
								});
							}
						});
					},
					fail: () => {
						uni.showToast({
							title: '下载失败',
							icon: 'none'
						});
					}
				});
			},
		}
	}
</script>

<style>
	.downloadbtn {
		margin: 0 auto;
		width: 300rpx;
		height: 100rpx;
		display: flex;
		align-items: center;
		justify-content: center;
		background: #007e00 !important;
		border-radius: 24px;
		font-size: 14px;
		margin-top: 12px;
		color: #fff !important;
	}
</style>

🧩关于图片接口

原计划是用网上的在线 API 接口来模拟从后台获取图片,比如说这个搏天 api 的随机壁纸接口,如下图的 https://api.btstu.cn/sjbz/api.php?lx=dongman&format=images 请求接口。
在这里插入图片描述
我们可以请求一下,看看返回的数据效果。
在这里插入图片描述
我们可以看到返回了一张壁纸,这张壁纸是在线的,后续我们会使用到。然后我们可以看到上面代码中的请求接口并不是用到这个在线 API ,而是 http://127.0.0.1:3000/getImage 这个本地写的 Nodejs 接口。接下来我们看看为什么不用这个在线 API ,以及如何写这个 Nodejs 接口。

首先看为什么不能用这个在线 API 的原因,我们在项目中请求看看,看看是否可以走完这个保存图片到本地的流程。我们可以发现这个接口请求返回的参数出现了乱码,而且在请求的响应过程非常缓慢,而且出现 302 的情况 (当服务器接收到请求后,可能会返回状态码为 302 的响应。这意味着您发送的请求需要进行临时重定向。在 302 响应中,服务器通常会在响应头中包含一个名为 “Location” 的字段,该字段指示了新的请求目标 URL。) ,接口是没有问题的,但是并不适用于这个页面的保存图片逻辑所需的图片文件路径。因此我们使用这个接口返回的图片的在线地址作为这个项目返回的参数,写一个本地的 Nodejs 服务。
在这里插入图片描述
接下来我们看看后台的代码,创建一个文件夹,然后新建一个 js 文件,然后在此文件下安装一个 Express 框架,具体操作如下。

  • 打开命令行界面
  • 在命令行界面中,进入您要创建 Express 应用程序的目录。
    在这里插入图片描述
  • 输入以下命令来初始化一个新的 Node.js 项目,并创建 package.json 文件:npm init
  • 安装 Express。在命令行界面中输入以下命令:npm install express

通过上面的步骤就可以创建好初始的结构了,然后是 js 代码,下面是 js 文件的完整代码。

const express = require('express');
const app = express();

// 定义接口路由
app.get('/getImage', (req, res) => {
  // 处理请求逻辑,获取图片路径或地址
  const imagePath = 'https://img.btstu.cn/api/images/5ab5ea3775fb5.jpg'; // 根据实际情况替换为图片的路径或地址
  // 返回图片路径或地址给前端
  res.json({ imagePath });
});

// 定义获取接口IP的路由
app.get('/getInterfaceIP', (req, res) => {
  // 获取服务器的IP地址
  const interfaceIP = req.headers.host.split(':')[0];
  // 返回接口IP给前端
  res.json({ interfaceIP });
});

// 定义接口用例地址路由
app.get('/getExampleAddress', (req, res) => {
  // 构建接口用例地址
  const exampleAddress = `http://${req.headers.host}/getImage`;
  // 返回接口用例地址给前端
  res.json({ exampleAddress });
});

// 启动服务器,监听指定端口
const port = 3000; // 你可以根据需要修改端口号
app.listen(port, () => {
  console.log(`Server is listening on port ${port}`);
});

最后通过 node xxx.js 启动这个本地服务,然后我们就可以去前端页面调用这个接口了,然后实现保存图片到本地的需求,接下来我们去尝试一下,首先是启动本地服务。
在这里插入图片描述
在这里插入图片描述
然后我们在小程序页面测试一下是否可以成功下载到图片。
在这里插入图片描述
最后点击保存按钮,即可保存成功,然后页面返回保存成功的提示即完成了该需求的功能,形成闭环。
在这里插入图片描述

🧩代码解析简述

关于这个项目的代码简述,这里就不过多介绍前端代码的逻辑了,因为在项目前置的知识点中已经大致介绍了该项目所需用到的 API 和大概的逻辑思路了。所以这里就简单介绍一下 Nodejs 的代码。

这段代码使用了 Express 框架创建了一个简单的服务器,该服务器有三个接口路由:

  • ‘/getImage’:返回图片路径或地址给前端;
  • ‘/getInterfaceIP’:获取服务器IP地址,并返回给前端;
  • ‘/getExampleAddress’:构建并返回 ‘/getImage’ 接口的完整请求地址给前端。

其中,对于每个路由,都通过 app.get() 方法进行定义,指定了请求方式为 GET 请求,并提供了相应的处理逻辑和响应。

最后,通过 app.listen() 方法启动服务器并监听指定的端口,以等待客户端发起请求。在本例中,指定的端口号是 3000。

当某个客户端向服务器发起 GET 请求时,如果请求路径匹配了其中之一的路由,则相应的处理逻辑会被执行,并向客户端返回相应的响应。


📝最后

到此就是本篇文章的全部内容了,这篇文章记录的主要内容的是模拟前端通过调用接口,然后获取到数据图片的路径数据,然后授权相册,最后把图片保存到本地(相册)的项目实战。这篇文章是博主 uni-app 专栏的实战篇的文章,后续会不断的更新更多关于 uni-app 的干货、实战经验、学习经验,期待你的关注和留言。
在这里插入图片描述

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

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

相关文章

YOLOv5改进 | 2023 | SCConv空间和通道重构卷积(精细化检测,又轻量又提点)

一、本文介绍 本文给大家带来的改进内容是SCConv,即空间和通道重构卷积,是一种发布于2023.9月份的一个新的改进机制。它的核心创新在于能够同时处理图像的空间(形状、结构)和通道(色彩、深度)信息,这样的处理方式使得SCConv在分析图像时更加精细和高效。这种技术不仅适…

DP专题9 理解01背包问题

本题链接&#xff1a;晴问算法 题目&#xff1a; 样例&#xff1a; 输入 5 8 3 5 1 2 2 4 5 2 1 3 输出 10 思路&#xff1a; 对于 01 背包问题&#xff0c;我们需要明确 DP 数组的含义&#xff0c;这里 经典的 01 背包问题可以用 二维DP进行表示。 即&#xff1a; dp[ i ]…

【C++】类和对象详解(类的使用,this指针)

文章目录 前言面向过程和面向对象的初步认识类的引入类的定义类的访问限定符和封装性访问限定符封装性 类的作用域类的实例化类对象模型如何计算类对象的大小类对象的存储方式猜测结构体内存对齐规则 this指针this指针的引出this指针的特性 总结 前言 提示&#xff1a;这里可以…

红帽Redhat安装教程及安装出错(Liunx)

一、红帽5安装 1.打开vmware,新建虚拟机。或者文件→新建虚拟机 2.自定义,下一步 3.下一步 4.稍后安装操作系统,下一步 5.linux 红帽5 64位,下一步 6.给虚拟机取名字,选择安装路径。下一步 7.下一步(可以根据自己的电脑配置稍微增加数量) 8.4GB 下一步 9.仅主机(根据需…

运维工程师——敢问路在何方!

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 ✨特色专栏&#xff1a…

[NISACTF 2022]popchains

[NISACTF 2022]popchains wp 题目代码&#xff1a; Happy New Year~ MAKE A WISH <?phpecho Happy New Year~ MAKE A WISH<br>;if(isset($_GET[wish])){unserialize($_GET[wish]); } else{$anew Road_is_Long;highlight_file(__FILE__); } /**********************…

RTT打印时间戳

官方的RTT VIEWER没有打印接收时间戳的功能&#xff0c;经过查找后发现可以有以下三种打印时间戳的方法。 第三方的RTT上位机ExtraPutty自己打印 第三方的RTT上位机 码云上有一个RTT_T2的仓库&#xff0c;基于python qt包写的画面&#xff0c;通过pylink来jlink通信。 优点…

CorelDRAW 2023 中文破解、终身永久版 (附序列号)

CorelDRAW2023是一款非常专业的电脑图像设计工具。该产品推出了全新的2023版本&#xff0c;在功能和体验上更进一步&#xff0c;最新的填充和透明设备功能可以完全控制任何类型的纹理&#xff0c;适用于网络摄影、印刷项目、艺术、排版等&#xff0c;让你可以更好的进行图像设计…

安全加密基础—基本概念、keytool、openssl

安全加密基础—基本概念、keytool、openssl 目录 前言 一、概念 明文通信 无密钥密文通信 对称加密 非对称加密 数字签名 消息摘要(MD5) CA数字证书(解决公钥分发的问题) HTTPS 相关文件扩展名 常用后缀名 普通的pem文件内容 二、keytool 2.1常用的命令如下 2…

网络优化篇(一)---------TCP重传性能优化

本文通过一个TCP重传优化的实际问题,详细讲解问题的分析、定位、优化过程。 通过本文你将学到: 如何通过linux命令和/proc文件系统分析TCP性能数据如何通过linux命令和netlink api分析某个具体的TCP连接的性能数据如何通过bcc工具分析TCP性能数据如何通过调整系统参数优化TCP重…

第1章 线性回归

一、基本概念 1、线性模型 2、线性模型可以看成&#xff1a;单层的神经网络 输入维度&#xff1a;d 输出维度&#xff1a;1 每个箭头代表权重 一个输入层&#xff0c;一个输出层 单层神经网络&#xff1a;带权重的层为1&#xff08;将权重和输入层放在一起&#xff09; 3、…

从零开始C++精讲:第一篇——C++入门

文章目录 前言一、C关键字二、命名空间2.1引子2.2命名空间定义2.3命名空间的使用 三、C输入和输出3.1输出3.2输入 四、缺省参数4.1全缺省4.2半缺省 五、函数重载5.1重载概念 六、引用6.1定义6.2引用的使用示例6.2.1引用作参数6.2.1引用作返回值 6.3传值、传引用效率比较6.4常引…

真空引水罐 虹吸抽水机 负压虹吸罐 农业灌溉工作原理动画介绍

​ 1&#xff1a;真空引水罐虹吸抽水机虹吸罐介绍 真空引水罐是一种水泵吸水设备&#xff0c;也被称为真空罐、吸水罐或自动引水装置。它是一个密封的罐体&#xff0c;被串联在泵前的吸水管上&#xff0c;能够使水泵的吸水口从负压吸水变为正压吸水。使用真空引水罐可以节省真…

彻底解决vue-video-player视频铺满div

需求 最近需要接入海康视频摄像头&#xff0c;然后把视频的画面接入到自己的网站系统中。以前对接过rtsp固定IP的显示视频&#xff0c;这次的不一样&#xff0c;没有了固定IP。海康的解决办法是&#xff0c;摄像头通过配置服务器到萤石云平台&#xff0c;然后购买企业版账号和…

解决vue3中watch 监听不到旧值的问题,亲测有效!

问题描述 这个问题是我在公司vue3项目的时候发现的一个问题&#xff0c;watch 在监听对象/数组变量的变化时&#xff0c;发现对象的数据变化时 旧数据 获取到的和新数据是一样的 类似于下面这样 const objref({a:我是原来的值,b:6, })obj.a改变值watch(obj,(nel,old)>{ c…

关于曲率、曲率半径和曲率圆,看这几篇文章就够啦

关于曲率、曲率半径和曲率圆的内容&#xff0c;是考研数学数学一和数学二大纲中明确要求掌握的内容&#xff0c;但这部分内容在很多教材教辅以及练习题中较少涉及。在本文中&#xff0c;荒原之梦考研数学网就为大家整理了曲率、曲率半径和曲率圆方程相关的概念、基础知识以及练…

无心剑七绝《译无止境》

七绝译无止境 人生跌宕几春秋 苦辣酸甜永不休 只待通灵成妙译 神思曼舞醉琼楼 2024年1月6日 平水韵十一尤平韵 无心剑的这首《译无止境》以七言绝句的形式&#xff0c;表达了对翻译事业的热爱和追求。 首句“人生跌宕几春秋”&#xff0c;意味着人生的曲折变化&#xff0c…

2024/1/7周报

文章目录 摘要Abstract文献阅读题目引言贡献相关工作Temporal RecommendationSequential Recommendation 方法Problem FormulationInput EmbeddingSelf-Attention StructureModel Training 实验数据集实验过程实验结果 深度学习Self-attention多头机制堆叠多层 总结 摘要 本周…

静态网页设计——宠物狗狗网(HTML+CSS+JavaScript)

前言 声明&#xff1a;该文章只是做技术分享&#xff0c;若侵权请联系我删除。&#xff01;&#xff01; 感谢大佬的视频&#xff1a; https://www.bilibili.com/video/BV1nk4y1X74M/?vd_source5f425e0074a7f92921f53ab87712357b 使用技术&#xff1a;HTMLCSSJS&#xff08;…

深度学习|4.1 深L层神经网络 4.2 深层网络的正向传播

4.1 深L层神经网络 对于某些问题来说&#xff0c;深层神经网络相对于浅层神经网络解决该问题的效果会较好。所以问题就变成了神经网络层数的设置。 其中 n [ i ] n^{[i]} n[i]表示第i层神经节点的个数&#xff0c; w [ l ] w^{[l]} w[l]代表计算第l层所采用的权重系数&#xff…