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

 

 效果截图

 

 

  

posted on 2022-08-25 09:36  小虾米吖~  阅读(2731)  评论(0编辑  收藏  举报