uniapp实现微信小程序端图片保存到相册

发布于:2025-07-12 ⋅ 阅读:(20) ⋅ 点赞:(0)

效果图展示

在这里插入图片描述

安装插件海报画板导入到项目里面,在页面直接使用

在这里插入图片描述

<template>
	<view>
		<button @click="saveToAlbum" class="save-button">保存到相册</button>
		<image :src="path" mode="widthFix" v-if="path" style="width: 100%;"></image>
		<!-- 绘图组件(保持hidden) -->
		<l-painter ref="painter" hidden isCanvasToTempFilePath @success="path = $event">
			<l-painter-view css="width:100%;line-height:90rpx;background:#efefef;text-align:center;">
				<l-painter-text text="分享好友得佣金,好友消费后佣金到账" css="color:blue;font-size:32rpx;"></l-painter-text>
			</l-painter-view>
			<l-painter-view 
			css="padding:30rpx;
				display: flex;
				flex-direction: column;
				align-items: flex-start;"
			>
				<l-painter-image css="width:100rpx;height:100rpx;border-radius:50rpx;" src="/static/logo.png"
					mode="aspectFill"></l-painter-image>
				<l-painter-text text="一颗葡萄" css="font-size:28rpx;padding-top:20rpx;"></l-painter-text>
				<l-painter-text text="共发布7篇 | 6分钟前发布" css="font-size:22rpx;color:#ccc"></l-painter-text>
				<l-painter-text text="合租-观山湖区-未来方舟;" css="font-size:40rpx;padding-top:20rpx;"></l-painter-text>
			</l-painter-view>
			<l-painter-view 
			css="padding:30rpx;
			display: flex;
			flex-wrap:wrap;
			align-items: flex-start;">
				<l-painter-image v-for="item in dataObj.house_images" css="width:30%;;border-radius:50rpx;" :src="item"
					mode="aspectFill"></l-painter-image>
			</l-painter-view>
		</l-painter>
		
	</view>
</template>

<script setup>
	import {
		ref,
		onMounted
	} from 'vue'
	const path = ref('')
	const painter = ref(null)
	const dataObj = ref({
		"house_images": [
			"https://renting-upload.oss-cn-chengdu.aliyuncs.com/App/20250707/1751852511187350583.png",
			"https://renting-upload.oss-cn-chengdu.aliyuncs.com/App/20250707/1751852516350361922.png",
			"https://renting-upload.oss-cn-chengdu.aliyuncs.com/App/20250707/175185252116150042.png",
			"https://renting-upload.oss-cn-chengdu.aliyuncs.com/App/20250707/1751852527581221874.png",
			"https://renting-upload.oss-cn-chengdu.aliyuncs.com/App/20250707/1751852533225847091.png",
			"https://renting-upload.oss-cn-chengdu.aliyuncs.com/App/20250707/1751852537888574703.png",
			"https://renting-upload.oss-cn-chengdu.aliyuncs.com/App/20250707/1751852542759268442.png",
			"https://renting-upload.oss-cn-chengdu.aliyuncs.com/App/20250707/1751852547136723025.png",
			"https://renting-upload.oss-cn-chengdu.aliyuncs.com/App/20250707/1751852551059965495.png"
		]
	})

	onMounted(() => {
		checkAuth()
	})

	const checkAuth = () => {
		uni.getSetting({
			success(res) {
				if (!res.authSetting['scope.writePhotosAlbum']) {
					uni.authorize({
						scope: 'scope.writePhotosAlbum',
						success() {
							console.log('授权成功')
						},
						fail() {
							console.log('授权失败')
						}
					})
				}
			}
		})
	}

	const saveToAlbum = async () => {
		if (!path.value) {
			uni.showToast({
				title: '图片尚未生成',
				icon: 'none'
			})
			return
		}

		try {
			const tempFilePath = await base64ToTempFilePath(path.value)
			await uni.saveImageToPhotosAlbum({
				filePath: tempFilePath
			})

			uni.showToast({
				title: '保存成功',
				icon: 'success'
			})
		} catch (err) {
			console.error('保存失败:', err)
			handleSaveError(err)
		}
	}

	const base64ToTempFilePath = (base64) => {
		return new Promise((resolve, reject) => {
			const base64Data = base64.replace(/^data:image\/\w+;base64,/, '')
			const filePath = `${wx.env.USER_DATA_PATH}/${Date.now()}.jpg`

			wx.getFileSystemManager().writeFile({
				filePath,
				data: base64Data,
				encoding: 'base64',
				success: () => resolve(filePath),
				fail: reject
			})
		})
	}

	const handleSaveError = (err) => {
		if (err.errMsg.includes('auth deny')) {
			uni.showModal({
				title: '提示',
				content: '需要相册权限才能保存图片',
				confirmText: '去设置',
				success: (res) => {
					if (res.confirm) {
						uni.openSetting()
					}
				}
			})
		} else {
			uni.showToast({
				title: '保存失败: ' + err.errMsg,
				icon: 'none'
			})
		}
	}
</script>

<style lang="scss" scoped>
	.save-button {
		margin: 40rpx;
		background-color: #ff5000;
		color: white;
		border-radius: 10rpx;

		&:active {
			opacity: 0.8;
		}
	}
</style>

网站公告

今日签到

点亮在社区的每一天
去签到