【微信小程序生成海报保存到相册】

微信小程序生成海报保存到相册

如图
需要先有设计图的尺寸
在这里插入图片描述
在这里插入图片描述

在canvas绘图时,通常会遇到的一种情况是用固定宽高来显示图片,如果直接把图片内容填充进去的话,显示出来的图片就会被压扁或者被挤瘦,其效果简直不忍直视!那么,就需要把图片进行拉伸、压缩或裁剪。

接下来,先给 drawImage 做个介绍:

canvas的drawImage函数可以 绘制图像到画布。

它有以下参数:

参数 类型 说明

参数说明
imageResource所要绘制的图片资源
sx源图像的矩形选择框的左上角 x 坐标
sy源图像的矩形选择框的左上角 y 坐标
sWidth源图像的矩形选择框的宽度
sHeight源图像的矩形选择框的高度
dx图像的左上角在目标 canvas 上 x 轴的位置
dy图像的左上角在目标 canvas 上 y 轴的位置
dWidth在目标画布上绘制图像的宽度,允许对绘制的图像进行缩放
dHeight在目标画布上绘制图像的高度,允许对绘制的图像进行缩放

这里再来一张图
在这里插入图片描述

它有三种写法:

  1. 只规定原始图片开始剪切的位置,默认填充剩余宽高到画布上

drawImage(imageResource, dx, dy)

  1. 从指定位置裁剪原始图片指定宽高,填充到画布上

drawImage(imageResource, dx, dy, dWidth, dHeight)

  1. 从指定位置裁剪原始图片指定宽高,从指定位置开始显示到画布上指定宽高

drawImage(imageResource, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)

这里如果需要裁剪图片的话需要用到第三种。

因为分享商品图片的话,图片的大小不固定,需要裁剪。
裁剪图片,借鉴这里


<!-- canvas -->
<view class="container">
    <button catchtap="showPic">点击生成海报</button>

    <!-- 分享 S -->
    <view class="share-cover" wx:if="{{showSharePic}}" catchtouchmove='true' catchtap='closeShare'>
    </view>
    <view class="share-pic-box" wx:if="{{showSharePic}}" >
        <view class="share-pic">
            <image src="{{sharePicUrl}}" class="sharePic"></image>
        </view>
        <button class="share-tips" catchtap='savePic'>保存图片</button>
        <!-- <view class="close-share" catchtap='closeShare'></view> -->
    </view>
    <!-- 分享 E -->

    <!-- canvas S -->
    <canvas canvas-id="shareFrends" class="canvas"></canvas>
    <!-- canvas E -->
</view>


/* fx */
.share-cover {
    width: 100%;
    height: 100%;
    position: fixed;
    top: 0;
    left: 0;
    background: rgba(0, 0, 0, .5);
    z-index: 101;
}

.share-pic-box {
    width: 640rpx;
    height: 1080rpx;
    border-radius: 24rpx;
    left: 50%;
    top: 45%;
    transform: translate(-50%, -50%);
    position: absolute;
    z-index: 999;
}

.share-pic {
    width: 640rpx;
    height: 1080rpx;
    border-radius: 24rpx;
    background: #fff;
    margin-bottom: 40rpx;
    overflow: hidden;
}

.share-tips {
    width: 70% !important;
    height: 44px;
    box-sizing: border-box;
    background: #FF3B3B;
    opacity: 1;
    border-radius: 22px;
    font-size: 16px;
    font-family: PingFang SC;
    font-weight: 400;
    line-height: 44px;
    color: #FFFFFF;
    padding: 0 !important;
}

/* .close-share {
    width: 50rpx;
    height: 50rpx;
    position: absolute;
    top: -25rpx;
    right: -25rpx;
    border-radius: 50%;
    z-index: 101;
    background-color: #fff;
    background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASBAMAAACk4JNkAAAALVBMVEUAAAAzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMFCKs1AAAADnRSTlMAAwGYnKilo/Tpjn6RhfLwgGgAAAB3SURBVAjXY7hxiAEEhLsZ+p4oABmMcS8Z7N45AVmi714xiL8DCjLGvTNiYKx75wQUeqzAABJUBAkxgARdwUIgwXcgIbAgVAik8QmEJQqUdYIKmYEFQWYp5gEFIcaLAQUhxjOCBP3AZokBXdAHMgso+JJh5yKoSwHamjhPbLDp2gAAAABJRU5ErkJggg==);
    background-size: 18rpx 18rpx;
    background-repeat: no-repeat;
    background-position: center center;
} */

.sharePic {
    width: 640rpx;
    height: 1080rpx;
}

.canvas {
    width: 1280rpx;
    height: 2160rpx;
    position: fixed;
    top: -1000000rpx;
}
Page({

    /**
     * 页面的初始数据
     */
    data: {
        shareImg: '',
        shareTitle: '',
 // canvas 
        showSharePic: false, // 分享海报显示隐藏
        sharePicUrl: '', // 生成海报连接
        _selData: {
            logoUrl: 'https:166073915600099c29f.jpg', //分享图
            headIcon: 'https:1658494314000538a44.png', //头像
            codeLogo: 'https:xxx/1660812259000a6a8e7.png', //小程序码
            buyLogoUrl: 'https://xxx/1660814336000e3ccda.png', //采购图标
        },
        imgInfo: {},
    },
  

     // 生命周期函数--监听页面加载
    * //分享的主图,一进来就获取图片信息、或者在拿到该数据之后就获取信息

    onLoad: function (options) { {
      // 获取图片信息
      // var that = this;
      wx.getImageInfo({
          src: this.data.shareImg,//分享的主图,一进来就获取图片信息、或者在拿到该数据之后就获取信息
          success(res) {
              console.log(res);
              that.setData({
                  imgInfo: res,//存起来要用到
              })
          }
      })
   },
    
    showPic() {
        let sharePicUrl = this.data.sharePicUrl;
        if (sharePicUrl != '') {
            this.setData({
                showSharePic: true
            })
        } else {
            wx.showToast({
                title: '图片生成中',
                mask: true,
                icon: 'loading',
                duration: 100000
            })
            this.share = false
            let logo = '';
            let headIcon = '';
            let code = '';
            let buyLogo = '';
            this.getHead().then(headUrl => {
                headIcon = headUrl
                return this.getLogo()
            }).then(logoUrl => {
                logo = logoUrl;
                return this.getCode() //getBuyLogo
            }).then(codeUrl => {
                code = codeUrl
                // this.drawImg(logo, headIcon, code);
                return this.getBuyLogo() //getBuyLogo
            }).then(buyLogoUrl => {
                buyLogo = buyLogoUrl
                this.drawImg(logo, headIcon, code, buyLogo);
            })
        }
    },
    // 绘图
    drawImg(logo, headIcon, code, buyLogo) {
        console.log(logo)
        console.log(headIcon)
        console.log(code)
        console.log(buyLogo)

        // let title = '家用小型熨烫机便携式蒸汽熨斗家用小型熨烫机便携式蒸汽熨斗家用小型熨烫机便携式蒸汽熨斗家用小型熨烫机便携式蒸汽熨斗' // 标题
        let title = this.data.shareTitle // 标题
        let authorName = 'var 有缘' // 名称

        let w = 0
        wx.getSystemInfo({
            success: function (res) {
                w = res.screenWidth
            }
        })

        // 1
        let ctx = wx.createCanvasContext('shareFrends')
        ctx.fillStyle = '#ffffff';//---------------设置背景色
        ctx.fillRect(0, 0, w / 750 * 1080 * 2, w / 750 * 1080 * 2) //600*600


        //绘制logo--分享主图 
        //开始画 
       	var dw = 580 / this.data.imgInfo.width;
        var dh = 580 / this.data.imgInfo.height;


        // 裁剪图片中间部分
        if (this.data.imgInfo.width > 580 && this.data.imgInfo.height > 580 || this.data.imgInfo.width < 580 && this.data.imgInfo.height < 580) {
            if (dw > dh) {
                ctx.drawImage(logo, 0, (this.data.imgInfo.height - 580 / dw) / 2, this.data.imgInfo.width, 580 / dw, 30, 30, w / 750 * 580 * 2, w / 750 * 580 * 2)
            } else {
                ctx.drawImage(logo, (this.data.imgInfo.width - 580 / dh) / 2, 0, 580 / dh, this.data.imgInfo.height, 30, 30, w / 750 * 580 * 2, w / 750 * 580 * 2)
            }
        }
        // 拉伸图片
        else {
            if (this.data.imgInfo.width < 580) {
                ctx.drawImage(logo, 0, (this.data.imgInfo.height - 580 / dw) / 2, this.data.imgInfo.width, 580 / dw, 30, 30, w / 750 * 580 * 2, w / 750 * 580 * 2)
            } else {
                ctx.drawImage(logo, (this.data.imgInfo.width - 580 / dh) / 2, 0, 580 / dh, this.data.imgInfo.height, 30, 30, w / 750 * 580 * 2, w / 750 * 580 * 2)
            }
        }


        // 标签 
        ctx.drawImage(buyLogo, w / 750 * 30 * 2, w / 750 * 640 * 2, w / 750 * 88 * 2, w / 750 * 40 * 2)

        //绘制标题
        ctx.setTextAlign('left');
        ctx.setFillStyle('#151521'); //title文字颜色
        ctx.setFontSize(w / 750 * 28 * 2);
        // ctx.fillText(title, w / 750 * 32 * 2, w / 750 * 780 * 2);
        let canvasTitleArray = title.split("");
        let firstTitle = ""; //第一行字
        let secondTitle = ""; //第二行字
        for (let i = 0; i < canvasTitleArray.length; i++) {
            let element = canvasTitleArray[i];
            let firstWidth = ctx.measureText(firstTitle).width;
            //console.log(ctx.measureText(firstTitle).width);
            if (firstWidth > (w / 750 * 550 * 2)) {
                let secondWidth = ctx.measureText(secondTitle).width;
                //第二行字数超过,变为...
                if (secondWidth > (w / 750 * 550 * 2)) {
                    secondTitle += "...";
                    break;
                } else {
                    secondTitle += element;
                }
            } else {
                firstTitle += element;
            }
        }
        //第一行文字
        // ctx.fillText(firstTitle, 20, 278, 280) //绘制文本
        ctx.fillText(firstTitle, w / 750 * 28 * 2, w / 750 * 730 * 2);
        //第二行问题
        if (secondTitle) {
            // ctx.fillText(secondTitle, 20, 300, 280) //绘制文本
            ctx.fillText(secondTitle, w / 750 * 28 * 2, w / 730 * 758 * 2);
        }

        // 价格
        let price = this.data.sharePrice // 标题
        let num = this.data.shareNum // 标题
        ctx.setFontSize(w / 750 * 32 * 2)
        ctx.setFillStyle('#ff3b39');
        //绘制文本
        ctx.fillText(`${price?'¥'+price:''}    ${num?'库存'+num:''}`, w / 750 * 32 * 2, w / 750 * 860 * 2)

        ctx.drawImage(code, w / 750 * 30 * 2, w / 750 * 880 * 2, w / 750 * 580 * 2, w / 750 * 200 * 2)
        //绘制文本 

        ctx.draw(false, () => {
            //调用接口将画布转换为图片
            wx.canvasToTempFilePath({
                x: 0,
                y: 0,
                fileType: 'jpg',
                quality: 1,
                width: w / 750 * 640 * 2,
                height: w / 750 * 1080 * 2,
                destWidth: w / 750 * 640 * 2,
                destHeight: w / 750 * 1080 * 2,
                canvasId: 'shareFrends',
                success: res => {

                    wx.hideToast();

                    this.setData({
                        sharePicUrl: res.tempFilePath //生成的图片路径
                    }, () => {

                        //渲染完后再显示分享海报
                        this.setData({
                            share: false,
                            showSharePic: true
                        })

                    })
                },
                fail(err) {
                    wx.showToast({
                        title: '图片生成失败,请稍候再试!',
                        icon: 'none',
                        mask: true
                    })
                }
            })
        })
    },

    //获取头像
    getHead() {
        return new Promise((resolve, reject) => {
            wx.downloadFile({
                url: this.data._selData.headIcon,
                success: res => {
                    resolve(res.tempFilePath)
                }
            })
        })
    },

    //获取logo
    // this.data.shareTitle,  this.data.shareImg,
    getLogo() {
        return new Promise((resolve, reject) => {
            wx.downloadFile({
                // url: this.data._selData.logoUrl,
                url: this.data.shareImg,
                success: res => {
                    resolve(res.tempFilePath);
                },
                fail: (err) => {
                    console.log(er)
                }
            })
        })
    },

    //获取二维码
    getCode() {
        return new Promise((resolve, reject) => {
            let tid = this.data._selData.tid;

            wx.downloadFile({
                url: this.data._selData.codeLogo,
                success: res => {
                    resolve(res.tempFilePath);
                },
                fail: (err) => {
                    console.log(er)
                }
            })
        })
    },
    //获取buyLogo
    getBuyLogo() {
        return new Promise((resolve, reject) => {
            wx.downloadFile({
                url: this.data._selData.buyLogoUrl,
                success: res => {
                    resolve(res.tempFilePath);
                },
                fail: (err) => {
                    console.log(err)
                }
            })
        })
    },


    //关闭分享海报
    closeShare() {
        this.setData({
            showSharePic: false
        })
    },

    //保存图片
    savePic() {
        let sharePicUrl = this.data.sharePicUrl;
        wx.getSetting({
            success: res => {
                if (res.authSetting['scope.writePhotosAlbum'] == false) {
                    wx.showModal({
                        title: '提示',
                        content: '是否授权将图片保存到相册?',
                        confirmColor: '#2ca2ed',
                        success: res => {
                            //点击确定打开授权设置
                            if (res.confirm) {

                                wx.openSetting({
                                    success: res => {

                                        setTimeout(() => {
                                            if (res.authSetting['scope.writePhotosAlbum'] == true) {

                                                wx.saveImageToPhotosAlbum({
                                                    filePath: sharePicUrl,
                                                    success: res => {
                                                        this.closeShare();
                                                        wx.showToast({
                                                            title: '已成功保存到相册!',
                                                            icon: 'none',
                                                            duration: 3000,
                                                        })
                                                    },
                                                    fail: err => {
                                                        wx.showToast({
                                                            title: '保存失败!',
                                                            icon: 'none',
                                                            duration: 3000,
                                                        })
                                                    }
                                                })
                                            } else {
                                                wx.showToast({
                                                    title: '保存失败!',
                                                    icon: 'none',
                                                    duration: 3000,
                                                })
                                            }
                                        }, 500)
                                    }
                                })
                            }
                        }
                    })
                } else {

                    wx.saveImageToPhotosAlbum({
                        filePath: sharePicUrl,
                        success: res => {
                            this.closeShare();
                            wx.showToast({
                                title: '已成功保存到相册!',
                                icon: 'none',
                                duration: 3000,
                            })
                        }
                    })

                }
            }
        })

    },

})
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值