04-13 4383人
微信小程序实现canvas按照原图等比例不失真绘制海报图,防止模糊
我这里的场景是收款二维码+收款背景图。
绘制二维码
我这里绘制二维码使用的 wxapp-qrcode ,也可以使用weapp-qrcode,基本都一样,详细代码不过多累赘,这里主要说下适配不同屏幕大小的canvas。
onLoad: function (options) {
const size = this.setCanvasSize() // 动态设置画布大小
this.createQrCode('www.iyouhun.com', "mycanvas", size.w, size.h)
},
// 适配不同屏幕大小的canvas
setCanvasSize: function () {
const size = {}
try {
const res = wx.getSystemInfoSync()
let scale = 750 / 686; // 不同屏幕下canvas的适配比例;设计稿是750宽,686是因为wxss样式文件中设置的canvas大小
let width = res.windowWidth / scale
let height = width; // canvas画布为正方形
size.w = width
size.h = height
} catch (e) {
console.log("获取设备信息失败" + e)
}
return size
},
绘制背景图
动态设置图片的高度和宽度
在小程序布局中,如果图片不是固定高度和高度,但image
设置的是固定的高度和宽度,这时候原始图片相对image
设置的固定高度和宽度不是等比例大小,那么这张图片就会变形,变的不清晰。这时就可以使用下面的等比例缩放的方式缩放图片,让图片不变形。或者通过image
的bindload
方法动态的获取图片的高度和宽度,动态的设置图片的高度和宽度,是图片布局的高度和宽度和原始图片的高度和宽度相等。
图片等比例缩放工具
//Util.js
class Util{
/***
* 按照显示图片的宽等比例缩放得到显示图片的高
* @params originalWidth 原始图片的宽
* @params originalHeight 原始图片的高
* @params imageWidth 显示图片的宽,如果不传就使用屏幕的宽
* 返回图片的宽高对象
***/
static imageZoomHeightUtil(originalWidth,originalHeight,imageWidth){
let imageSize = {};
if(imageWidth){
imageSize.imageWidth = imageWidth;
imageSize.imageHeight = (imageWidth * originalHeight) / originalWidth;
}else{//如果没有传imageWidth,使用屏幕的宽
wx.getSystemInfo({
success: function (res) {
imageWidth = res.windowWidth;
imageSize.imageWidth = imageWidth;
imageSize.imageHeight = (imageWidth * originalHeight) / originalWidth;
}
});
}
return imageSize;
}
/***
* 按照显示图片的高等比例缩放得到显示图片的宽
* @params originalWidth 原始图片的宽
* @params originalHeight 原始图片的高
* @params imageHeight 显示图片的高,如果不传就使用屏幕的高
* 返回图片的宽高对象
***/
static imageZoomWidthUtil(originalWidth,originalHeight,imageHeight){
let imageSize = {};
if(imageHeight){
imageSize.imageWidth = (imageHeight *originalWidth) / originalHeight;
imageSize.imageHeight = imageHeight;
}else{//如果没有传imageHeight,使用屏幕的高
wx.getSystemInfo({
success: function (res) {
imageHeight = res.windowHeight;
imageSize.imageWidth = (imageHeight *originalWidth) / originalHeight;
imageSize.imageHeight = imageHeight;
}
});
}
return imageSize;
}
}
export default Util;
工具库使用
<image bindload="imageLoad" src="../test.png"/>
import Util from '../common/Util'
Page({
data:{
imageWidth:0,
imageHeight:0
},
imageLoad: function (e) {
//获取图片的原始宽度和高度
let originalWidth = e.detail.width
let originalHeight = e.detail.height
let imageSize = Util.imageZoomWidthUtil(originalWidth,originalHeight,145)
this.setData({imageWidth:imageSize.imageWidth,imageHeight:imageSize.imageHeight})
}
})
绘制背景图
用上面的方法动态设置图片宽高,解决失真问题
import Util from '../../libs/Util'
// 背景图
let bgImg = new Promise(function (resolve) {
wx.getImageInfo({
src: 'https://www.iyouhun.com/payment/payment_pic.jpg',
success: function (res) {
that.setData({
imgInfo: res
})
// 根据屏幕宽度得到图片高
const imageSize = Util.imageZoomHeightUtil(that.data.imgInfo.width, that.data.imgInfo.height)
that.setData({ canvasHeight: imageSize.imageHeight })
resolve(res.path)
},
fail: function (err) {
console.log(err)
wx.showToast({
title: '网络错误请重试',
icon: 'loading'
})
}
})
})
合成海报/收款码
这里使用Promise
分别去绘制二维码和背景图。
// 收款码
let qrcodeImg = new Promise(function (resolve) {
// ...
})
// 背景图
let bgImg = new Promise(function (resolve) {
// ...
}
Promise.all([bgImg, qrcodeImg]).then(function(result) {
wx.showLoading({title: '加载中'})
// canvas绘制文字和图片,创建画图
const ctx = wx.createCanvasContext('myCanvas')
// 绘制背景图
ctx.drawImage(result[0], 0, 0, that.data.imgInfo.width, that.data.imgInfo.height, 0, 0, that.data.canvasWidth, that.data.canvasHeight)
ctx.setFillStyle('white')
// 绘制二维码 二维码宽度300
const qrX = (that.data.canvasWidth - 300) / 2 // canvas宽度 - 二维码宽度 / 2 (居中)
ctx.drawImage(result[1], qrX, 120, 300, 300)
// 绘制文本
ctx.fillStyle = '#ffffff' // 背景
ctx.fillRect(Math.floor(qrX),420,300,20)
ctx.fillStyle = "#333333"
ctx.font = 25 + 'px Arial' // 文本大小, 字体
ctx.textAlign = 'center'
ctx.fillText(
'No.'+ that.data.serialNum,
that.data.canvasWidth / 2, // 左上角 X坐标
430, // 左上角 Y坐标
300
)
//canvasToTempFilePath必须要在draw的回调中执行,否则会生成失败,官方文档有说明
ctx.draw(false, setTimeout(function () {
wx.canvasToTempFilePath({
canvasId: 'myCanvas',
x: 0,
y: 0,
width: that.data.canvasWidth,
height: that.data.canvasHeight,
success: function (res) {
wx.hideLoading()
that.setData({
qrcodeStatus: true,
shareImgSrc: res.tempFilePath
})
},
fail: function (res) {
wx.hideLoading()
wx.showToast({
title: '生成失败',
icon: "none"
})
}
})
}, 1000))
})
效果图
鸟叔来贵博客参观学习,期待回访!
Everything composed was actually very logical. But, think about this, what if you
added a little content? I mean, I don't want to tell you how to run your blog, however what if
you added a post title to maybe grab people's attention? I
mean 小程序canvas生成海报图片压缩和失真问题解决 - 游魂博客-分享技术,资源共享 is
kinda boring. You should glance at Yahoo's front page and watch how
they write news headlines to grab people interested.
You might add a video or a pic or two to grab readers excited about what you've got to say.
Just my opinion, it might bring your posts a little livelier.
I usually ddo not create many comments, buut after reading
a few of the responses on this page 小程序canvas生成海报图片压缩和失真问题解决 - 游魂博客-分享技术,资源共享.
I do have 2 questions for you if it's allright. Could iit bee simpoly me
or does it appear like some of thewse comments appear like they are written by
brain dead individuals? :-P And, if you are posting on other social sites,
I'd like to keep up with you. Could you post a list of the complete urls off all your shared pages
likee your Facebook page, twitter feed, oor linkedin profile?
鸟叔来访,欢迎回访
Thanks for sharing your thoughts on 微信小程序.
Regards
Thanks for sharing your thoughts about 微信小程序.
Regards