uni-app微信小程序保存照片(照片是两张照片合并成canvas的另一张图片)到相册
背景:
1、若是使用了 uni.downloadFile(),那么使用的url必须是http或者https开头的图片,这是官方的,实际使用你会发现模拟器确实是http开头的图片,但是开发版、体验版、真机测试等获取到的图片是 wx://http/temp... 开头的,即根本没办法拿到指定图片,解决方案是先上传图片(将图片转换为https开头的网络图片后再下载)
2、不使用 uni.downloadFile() 也可以将图片保存至相册,并且无需上传,无需转化图片路径,即便是 wx://http/temp..格式的也没关系。
一)使用上传下载功能的实现方式-全部代码
<template>
<view class="cloud_box">
<view class="titels">换头像活动</view>
<view class="box">
<view v-for="(item,index) in modelList" :key="index" class="items" @tap="clickTab(index)">
<view class="border" :class="currentIndex==index?'active':''">
<image :src="item.url" class="model_img"></image>
</view>
</view>
</view>
<view class="result">
<view class="left border active">
<image :src="modelList[currentIndex].url" class="model_img"></image>
<image :src="chooseImg" class="choose_img"></image>
</view>
<view class="flex_flow">
<button type="primary" @tap="uploadFile">上传图片</button>
<button type="warn" @tap="showResult">保存头像</button>
</view>
</view>
<canvas style=" width: 750rpx; height: 500rpx;opacity: 0;" canvas-id="myApp" id="myApp"> </canvas>
<gmy-img-cropper ref="gmyImgCropper" :quality="1" cropperType="fixed" :imgSrc="imgSrc" @getImg="getImg"></gmy-img-cropper>
</view>
</template>
<script>
import gmyImgCropper from '@/components/uni-img-cropper/index.vue';
export default {
components: {
gmyImgCropper
},
data() {
return {
modelList: [{
url: 'https://oss.light-hearted.cn/storage/061e7b3940b5b2946aa5d99ff72115923a860cf320220818135359.png'
},
{
url: 'https://oss.light-hearted.cn/storage/cc2b80c16c949f5a28c8a6cca013d3ea3ca810da20220818140442.png'
},
{
url: 'https://oss.light-hearted.cn/storage/c92fa168bf46c02384fe96f3155515f3db5ed24b20220818150820.png'
}
],
currentIndex: 0,
chooseImg: '',
result_img: '',
chooseImg_result:''//选择后上传可以使用的图片
}
},
onLoad() {
this.initCavas();
},
methods: {
/* 初始化canvas */
initCavas() {
this.cavasCtx = uni.createCanvasContext('myApp', this)
},
clickTab(_index) {
this.currentIndex = _index;
this.createCanvas(this.chooseImg_result);
},
/* 上传头像 */
uploadFile(e) {
// 调用实例的chooseImg方法,拉起图片选择界面,待图片选择完毕后直接进入图片截取界面
this.$refs.gmyImgCropper.chooseImage(e);
},
//裁剪图片的临时路径
getImg(e) {
this.chooseImg = e;
uni.uploadFile({
url: "上传路径",
filePath: this.chooseImg,
fileType: "image",
name: 'image',
formData: {
'file': this.chooseImg
},
success: (result) => {
let _result = JSON.parse(result.data);
this.chooseImg_result = _result.data.url;
if (_result.code == 1) {
this.createCanvas(this.chooseImg_result);
}
},
fail: function(fail) {
uni.showToast({
title: "上传失败",
icon: "none"
})
},
});
},
/* 创建画布 */
createCanvas(_url) {
let _this = this;
uni.downloadFile({
url: _url,
success: function(res) {
_this.cavasCtx.save()
_this.cavasCtx.beginPath()
// _this.cavasCtx.arc(100, 100, 100, 0, 2 * Math.PI) // 圆形
_this.cavasCtx.rect(0, 0, 200, 200) // 矩形
_this.cavasCtx.clip()
_this.cavasCtx.drawImage(res.tempFilePath, 0, 0, 200, 200)
_this.drapImg()
},
complete: (res) => {
}
})
},
/* 开始作画 */
drapImg() {
let _this = this;
uni.showLoading({
title: '上传合成中...',
icon: "loading"
});
uni.getImageInfo({
src: _this.modelList[_this.currentIndex].url,
complete: (res) => {
_this.cavasCtx.drawImage(res.path, 0, 0, 200, 200);
_this.cavasCtx.draw();
setTimeout(() => {
_this.putOut();
}, 100)
}
})
},
/* 两张图片合成成功 */
putOut() {
console.log('putOut')
let _this = this;
uni.canvasToTempFilePath({
x: 0,
y: 0,
width: 200,
height: 200,
canvasId: 'myApp',
success: function(res) {
uni.hideLoading();
uni.uploadFile({
url: "上传路径",
filePath: res.tempFilePath,
fileType: "image",
name: 'image',
formData: {
'file': res.tempFilePath
},
success: (result) => {
let _result = JSON.parse(result.data);
if (_result.code == 1) {
uni.showToast({
title: "上传合成成功",
icon: "none"
})
_this.result_img = _result.data.url;
}
},
fail: function(fail) {
uni.showToast({
title: "合成失败",
icon: "none"
})
},
});
}
})
},
// 保存图片到本地
showResult() {
uni.showLoading({
title: '保存中...',
icon: 'loading'
})
let that = this;
// 向用户发起授权请求
uni.authorize({
scope: 'scope.writePhotosAlbum',
success: () => {
// 已授权
that.downLoadImg();
},
fail: () => {
// 拒绝授权,获取当前设置
uni.getSetting({
success: (result) => {
if (!result.authSetting['scope.writePhotosAlbum']) {
that.isAuth()
}
}
});
}
})
},
/**
* 下载资源,保存图片到系统相册
*/
downLoadImg() {
let _this = this;
uni.showLoading({
title: '加载中'
});
if(_this.result_img){
uni.downloadFile({
url: _this.result_img,
success: (res) => {
uni.hideLoading();
if (res.statusCode === 200) {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: function() {
uni.hideLoading();
uni.showModal({
title: "保存成功",
content: "头像已经在您的相册里啦",
showCancel: false
})
},
fail: function(res) {
console.log('err_res', res);
uni.hideLoading();
uni.showToast({
title: "保存失败,请稍后重试",
icon: "none"
});
}
});
}
},
fail: (err) => {
uni.hideLoading();
console.log('err', err);
uni.showToast({
title: "失败啦",
icon: "none"
});
}
});
}else{
uni.showLoading({
title: '获取资源中...',
icon:"none"
});
}
},
/*
* 引导用户开启权限
*/
isAuth() {
uni.showModal({
content: '由于您还没有允许保存图片到您相册里,无法进行保存,请点击确定允许授权',
success: (res) => {
if (res.confirm) {
uni.openSetting({
success: (result) => {
console.log(result.authSetting);
}
});
}
}
});
},
}
}
</script>
<style>
@import url("cloudHead.css");
</style>
二)不使用上传下载功能的实现方式(推荐)
<template>
<view class="cloud_box">
<view class="titels">换头像活动</view>
<view class="box">
<view v-for="(item,index) in modelList" :key="index" class="items" @tap="clickTab(index)">
<view class="border" :class="currentIndex==index?'active':''">
<image :src="item.url" class="model_img"></image>
</view>
</view>
</view>
<view class="result">
<view class="left border active">
<image :src="modelList[currentIndex].url" class="model_img"></image>
<image :src="chooseImg" class="choose_img"></image>
</view>
<view class="flex_flow">
<button type="primary" @tap="uploadFile">上传图片</button>
<button type="warn" @tap="showResult">保存头像</button>
</view>
</view>
<canvas style=" width: 750rpx; height: 500rpx;opacity: 0;" canvas-id="myApp" id="myApp"> </canvas>
<gmy-img-cropper ref="gmyImgCropper" :quality="1" cropperType="fixed" :imgSrc="imgSrc" @getImg="getImg"></gmy-img-cropper>
</view>
</template>
<script>
import gmyImgCropper from '@/components/uni-img-cropper/index.vue';
export default {
components: {
gmyImgCropper
},
data() {
return {
modelList: [{
url: 'https://oss.light-hearted.cn/storage/061e7b3940b5b2946aa5d99ff72115923a860cf320220818135359.png'
},
{
url: 'https://oss.light-hearted.cn/storage/cc2b80c16c949f5a28c8a6cca013d3ea3ca810da20220818140442.png'
},
{
url: 'https://oss.light-hearted.cn/storage/c92fa168bf46c02384fe96f3155515f3db5ed24b20220818150820.png'
}
],
currentIndex: 0,
chooseImg: '',
result_img: '',
}
},
onLoad() {
this.initCavas();
},
methods: {
/* 初始化canvas */
initCavas() {
this.cavasCtx = uni.createCanvasContext('myApp', this)
},
clickTab(_index) {
this.currentIndex = _index;
if(this.chooseImg){
this.createCanvas(this.chooseImg);
}
},
/* 上传头像 */
uploadFile(e) {
// 调用实例的chooseImg方法,拉起图片选择界面,待图片选择完毕后直接进入图片截取界面
this.$refs.gmyImgCropper.chooseImage(e);
},
//裁剪图片的临时路径
getImg(e) {
this.chooseImg = e;
this.createCanvas(this.chooseImg);
},
/* 创建画布 */
createCanvas(_url) {
let _this = this;
_this.cavasCtx.save()
_this.cavasCtx.beginPath()
// _this.cavasCtx.arc(100, 100, 100, 0, 2 * Math.PI) // 圆形
_this.cavasCtx.rect(0, 0, 200, 200) // 矩形
_this.cavasCtx.clip()
_this.cavasCtx.drawImage(_url, 0, 0, 200, 200)
_this.drapImg()
},
/* 开始作画 */
drapImg() {
let _this = this;
uni.showLoading({
title: '上传合成中...',
icon: "loading"
});
uni.getImageInfo({
src: _this.modelList[_this.currentIndex].url,
complete: (res) => {
_this.cavasCtx.drawImage(res.path, 0, 0, 200, 200);
_this.cavasCtx.draw();
setTimeout(() => {
_this.putOut();
}, 100)
}
})
},
/* 两张图片合成成功 */
putOut() {
console.log('putOut')
let _this = this;
uni.canvasToTempFilePath({
x: 0,
y: 0,
width: 200,
height: 200,
canvasId: 'myApp',
success: function(res) {
uni.hideLoading();
_this.result_img = res.tempFilePath;
}
})
},
// 保存图片到本地
showResult() {
uni.showLoading({
title: '保存中...',
icon: 'loading'
})
let that = this;
// 向用户发起授权请求
uni.authorize({
scope: 'scope.writePhotosAlbum',
success: () => {
// 已授权
that.downLoadImg();
},
fail: () => {
// 拒绝授权,获取当前设置
uni.getSetting({
success: (result) => {
if (!result.authSetting['scope.writePhotosAlbum']) {
that.isAuth()
}
}
});
}
})
},
/**
* 下载资源,保存图片到系统相册
*/
downLoadImg() {
let _this = this;
uni.showLoading({
title: '保存中...'
});
if(_this.result_img){
uni.saveImageToPhotosAlbum({
filePath: _this.result_img,
success: function() {
uni.hideLoading();
uni.showModal({
title: "保存成功",
content: "头像已经在您的相册里啦",
showCancel: false
})
},
fail: function(res) {
console.log('err_res', res);
uni.hideLoading();
uni.showToast({
title: "保存失败,请稍后重试",
icon: "none"
});
}
});
}else{
uni.showLoading({
title: '图片合成中...',
icon:"none"
});
}
},
/*
* 引导用户开启权限
*/
isAuth() {
uni.showModal({
content: '由于您还没有允许保存图片到您相册里,无法进行保存,请点击确定允许授权',
success: (res) => {
if (res.confirm) {
uni.openSetting({
success: (result) => {
console.log(result.authSetting);
}
});
}
}
});
},
}
}
</script>
<style>
@import url("cloudHead.css");
</style>
gmyImgCropper 图片裁剪插件源码见上一篇博客 https://www.cnblogs.com/LindaBlog/p/16612920.html
效果截图
本文来自博客园,作者:小虾米吖~,转载请注明原文链接:https://www.cnblogs.com/LindaBlog/p/16623186.html