uniapp(Vue)开发微信小程序 之 保存图片到本地

一、保存图片到本地(要拿到图片的 src):

查看隐私条约是否加上相册(仅写入)权限:

微信公众平台 -》 左下角头像 -》账号设置 -》 用户隐私保护指引 -》去完善 -》 相册(仅写入)权限


1、判断用户是否授权相册权限:uni.getSetting

2、让用户授权:

① 引导用户授权:uni.authorize

② 通过设置让用户授权:uni.openSetting

3、下载图片:uni.downloadFile

4、保存到本地:uni.saveImageToPhotosAlbum

5、完整代码(包含文件的重命名):

javascript 复制代码
// 点击下载按钮 -- 进行授权
downLoad() {
	const that = this
	uni.getSetting({ 
		success: function(res) {
			if (res.authSetting['scope.writePhotosAlbum']) { // 用户授权相册权限
				that.saveImg()
			} else { // 用户没有授权相册权限
				uni.showModal({
					title: '提示',
					content: '用户未授权相册权限,点击授权',
					success: function (res) {
						if (res.confirm) {
							 uni.authorize({
								scope: 'scope.writePhotosAlbum',
								success: () => {
									that.saveImg()
								},
								fail: () => { // 用户拒绝授权,引导手动开启
								  uni.showModal({
										title: '提示',
										content: '需授权相册权限才能保存图片',
										success: (res) => {
										  if (res.confirm) uni.openSetting();
										}
								  });
							  }	,
							})
						} else {
							uni.showToast({
							  title: "用户取消授权,不能使用下载功能",
							  icon: "error",
							})
						}
					},
				})
			}
		},
		fail: function(error) {
			uni.showToast({
			  title: "查询授权失败",
			  icon: "error",
			})
		}
	})
},
// 保存图片 -- 直接保存,不做重命名处理
saveImg() {
	const that = this
	uni.saveImageToPhotosAlbum({
		filePath: `图片的src`,
		success: res => {
			uni.showToast({title: "保存成功",icon: "success"})
		},
		fail: err => {
			console.log(err)
		}
	});
},
// 保存图片 -- 使用 uni.downloadFile 做重命名处理,ios会报错
saveImg2() {
 const that = this
 const newName = this.formatFileName('这是图片的新名字');
 uni.downloadFile({
 	url:  `图片的src`,
 	filePath: uni.env.USER_DATA_PATH + "/" + newName + ".png",
 	success(res) {
 		if (res.statusCode === 200) {
 			// 下载成功开始保存图片
 			uni.saveImageToPhotosAlbum({
 				filePath: res.tempFilePath,
 				success: function() {
 					uni.showToast({
 					  title: "保存成功",
 					  icon: "success",
 				   })
 
 				},
 				fail: function(error) {
 					uni.showToast({
 					  title: "保存失败",
 					  icon: "error",
 					})
 
 				}
 			})
 		}
 	},
 	fail(error) {
 		// 下载失败输出错误信息
 		 // that.showToast('下载失败')
 		console.log('下载失败', error)
 	}
 })
},
// 文件重命名,使用fs
saveImg3() {
	const that = this
	const newName = this.formatFileName('新名字');
	const fs = uni.getFileSystemManager();
	let codeImg = this.qrcode.src
	fs.readFile({
	    filePath: '图片的临时路径', // 例如:'/path/to/your/image.jpg'
	    encoding: 'base64', // 指定编码格式为base64
	    success: function (res) {
			var byte= res.data.replace("data:image/png;base64,","");
			fs.writeFile({
				filePath: uni.env.USER_DATA_PATH + "/" + newName + ".png", // fileName 需要保存的文件名称 (文件后缀根据需要修改)
				data: byte,
				encoding: "base64",
				success: (downloadRes) => {
					console.log("this.qrcode.codeUrl",downloadRes)
					uni.saveImageToPhotosAlbum({
						filePath: uni.env.USER_DATA_PATH + "/" + newName + ".png",
						success: res => {
							uni.showToast({title: "保存成功",icon: "success"})
						},
						fail: err => {
							console.log(err)
						}
					});
				},
				fail: (err) => {
					console.log(err);
					uni.showToast({
						icon: 'none',
						mask: true,
						title: '文件下载失败',
					});
				},
			});
	    },
	    fail: function (err) {
	        console.error(err);
	    }
	});
},
formatFileName(name) {
	return decodeURIComponent(name)
		.replace(/%20/g, '')
		.replace(/#/g, '%23');
},

6、文件的重命名ios报错:

解决:

① 检查downloadFile合法域名

使用fs转base64

二、蓝牙连接打印机(使用了插件):

1、开启蓝牙权限:

javascript 复制代码
"permission" : {
	"scope.userLocation": {
		"desc": "蓝牙搜索"
	},
	"scope.bluetooth": {
		"desc": "蓝牙搜索"
	}
},

2、下载要使用的sdk,并且根据说明进行引入:

去官网找,根据平台进行下载。

举例使用的:https://www.detonger.com/#/

① 本文通过DCloud 插件市场下载

② 引入:

javascript 复制代码
import {LPAPIFactory} from "@/uni_modules/dothan-lpapi-ble/js_sdk/index.js";

③ 初始化数据:

javascript 复制代码
lpapi: null, // 打印对象
canvasId: "lpapi-ble-uni", // 绘图对象
labelWidth: 0, // 打印的宽度(单位mm)
labelHeight: 0,
printMode: 0, // 0是打印,1是预览
rotationIndex: 0,
rotationList: [{
	name: "横向打印",
	value: 0
},
{
	name: "右转90度",
	value: 90
},
{
	name: "转转180度",
	value: 180
},
{
	name: "左转90度",
	value: 270
},
],
gapList: [{
	name: "随打印机设置",
	value: 255
},
{
	name: "小票纸",
	value: 0
},
{
	name: "不干胶",
	value: 2
},
{
	name: "卡纸",
	value: 3
},
],
gapIndex: 0,
darknessList: [{
	name: "随打印机设置",
	value: 255
},
{
	name: "6 (正常)",
	value: 6
},
{
	name: "7",
	value: 7
},
{
	name: "8",
	value: 8
},
{
	name: "9",
	value: 9
},
{
	name: "10 (较浓)",
	value: 10
},
{
	name: "11",
	value: 11
},
{
	name: "12",
	value: 12
},
{
	name: "13",
	value: 13
},
{
	name: "14",
	value: 14
},
{
	name: "15 (最浓)",
	value: 15
},
],
darknessIndex: 0,
speedList: [{
	name: "随打印机设置",
	value: 255
},
{
	name: "最慢",
	value: 1
},
{
	name: "较慢",
	value: 2
},
{
	name: "正常",
	value: 3
},
{
	name: "较快",
	value: 4
},
{
	name: "最快",
	value: 5
},
],
speedIndex: 0,

④ 存储绘制好的图片:

javascript 复制代码
<canvas :id="canvasId" :canvas-id="canvasId"
:style="{width: labelWidth + 'rpx', height: labelHeight + 'rpx'}"
style="position: fixed;left: -999999rpx;top: -999999rpx;" />

⑤ 点击按钮开始打印:

javascript 复制代码
printCode() {
	const that = this
	that.lpapi = LPAPIFactory.getInstance({
		// 日志信息显示级别,值为 0 - 4,0表示不显示调试信息,4表示显示所有调试信息
		showLog: 4,
		// 钉钉小程序需要备注下,UniApp无法识别钉钉小程序。
		// isDingTalk: this.isAlipay ? true : false,
		// enablePageKey: true,
		// bleAdapter: bleAdapter,
	});
	// 搜索蓝牙设备
	that.lpapi.startBleDiscovery({
		timeout: 0,
		deviceFound: (res) => {
			let devices = res[0]
			console.log('打印机设备', devices)
			if (devices && devices.deviceId) {
				uni.showLoading({
					title: "正在链接打印机...",
				});
				this.lpapi.openPrinter({
					name: devices.name,
					deviceId: devices.deviceId,
					// 如果打印机链接失败的话,可以尝试连续进行多次链接。
					// tryTimes: isAlipay ? 1 : 5,
					success: (resp) => {
						console.log(`---- 【打印机链接成功】`);
						console.log(resp.resultInfo);
						uni.hideLoading();
						uni.showToast({
							title: "打印机链接成功!",
							icon: "success"
						});
						that.printModel()
					},
					fail: (resp) => {
						console.warn(`---- 【打印机链接失败】:`);
						console.warn(JSON.stringify(resp));
						//
						uni.hideLoading();
						//
						uni.showToast({
							title: "打印机链接失败!",
							icon: "fail"
						});
					},
				});
			} else {
				console.warn("---- 未检测到打印机!");
				uni.showToast({
					title: "未检测到打印机",
					icon: "fail"
				});
			}
		},
	});
},
// 开始打印
printModel() {
	const that = this
	const api = that.lpapi;
	let data = {
		"name": "这是一个标题",
		"address": "这是地址,太长的话会换行,哈哈哈哈哈",
		"type": "1" // 根据要求来调整样式,一个是横版,一个是竖版
	}
	
	let jobInfo = null
	if(data.type == 1) {
		that.labelWidth = 70
		that.labelHeight = 50
		that.rotationIndex = 1
		jobInfo = api.startJob({
			width: that.labelWidth,
			height: that.labelHeight,
			orientation: that.getOrientation(),
			jobName: that.getJobName(),
		});
		if (!jobInfo) {
			console.warn("---------- 打印任务创建失败!----------");
			return false;
		}
		api.drawText({ text: data.name, x: 4, y: 5, fontHeight: 4 });
		api.drawText({ width: 24, height: 8, text: '地址:'+data.address, x: 4, y: 14, fontHeight: 3 });
		// 二维码
		api.draw2DQRCode({
			text: '这是二维码的链接',
			x: 44,
			y: 11,
			width: 21,
		});
		// 横线
		api.drawLine({ x1: 4, x2: 66, y1: 40,y2: 40, lineWidth: 0.1 });
		api.drawText({ text: '这就是结束了', x: 4, y: 42, fontHeight: 3 });
	} else {
		that.labelWidth = 50
		that.labelHeight = 70
		that.rotationIndex = 0
		jobInfo = api.startJob({
			width: that.labelWidth,
			height: that.labelHeight,
			orientation: that.getOrientation(),
			jobName: that.getJobName(),
		});
		if (!jobInfo) {
			console.warn("---------- 打印任务创建失败!----------");
			return false;
		}
		let textlen = data.modelName.length * 2
		let itemWidth = that.labelWidth / 2
		api.drawText({ text: data.name, x: itemWidth - textlen, y: 3, fontHeight: 4 });
		// 二维码
		api.draw2DQRCode({
			text: '这是二维码的链接',
			x: itemWidth - 11,
			y: 11,
			width: 21,
			horizontalAlignment: 1,
		});
		api.drawText({ text: '这就是结束了', x: 4, y: 42, fontHeight: 3 });
	}
	
	api.commitJob({
		gapType: that.getGapType(),
		printDarkness: that.getPrintDarkness(),
		printSpeed: that.getPrintSpeed(),
	}).then((resp) => {
		// this.previewLabel(resp);
		console.log('打印完毕',resp)
		return resp.statusCode === 0;
	});
},
getJobName() {
	if (this.printMode === 1) {
		return "#!#preview#!#";
	} else if (this.printMode === 2) {
		return "#!#transparent#!#";
	} else {
		return "lpapi-ble";
	}
},
getOrientation() {
	return this.rotationList[this.rotationIndex].value;
},
getGapType() {
	return this.gapList[this.gapIndex].value;
},
getPrintDarkness() {
	return this.darknessList[this.darknessIndex].value;
},
getPrintSpeed() {
	return this.speedList[this.speedIndex].value;
},
相关推荐
a东方青39 分钟前
vue3学习笔记之属性绑定
vue.js·笔记·学习
沉默是金~1 小时前
Vue+Notification 自定义消息通知组件 支持数据分页 实时更新
javascript·vue.js·elementui
上趣工作室1 小时前
vue3专题1------父组件中更改子组件的属性
前端·javascript·vue.js
只会安静敲代码的 小周4 小时前
【长按图片识别】uniapp vue开发时,点击图片识别—实现转发、收藏、识别图片二维码
前端·vue.js·uni-app
F26017755924 小时前
uniapp中uni-easyinput 使用@input 不改变绑定的值
java·前端·uni-app
清风细雨_林木木4 小时前
小程序返回按钮,兼容所有机型的高度办法
微信小程序·小程序
shmily ....4 小时前
从零构建 Vue3 登录页:结合 Vant 组件与 Axios 实现完整登录功能
前端·javascript·vue.js
杯莫停丶4 小时前
基于uniapp的鸿蒙APP大数据量性能优化
性能优化·uni-app·harmonyos·鸿蒙
code袁4 小时前
基于微信小程序的中医小妙招系统的设计与实现
微信小程序·小程序·notepad++·小程序开发·中医小妙招