04-13 4085人
微信小程序实现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))
})
效果图
鸟叔来贵博客参观学习,期待回访!
Windows 7 x64 Google Chrome 100.0.4896.60Everything composed was actually very logical. But, think about this, what if you
Mac OS X 10.12.4 Google Chrome 66.0.3359.181added 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
Mac OS X 10.12.6 Google Chrome 66.0.3359.81a 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?
鸟叔来访,欢迎回访
Windows 7 x64 Google Chrome 100.0.4896.60Thanks for sharing your thoughts on 微信小程序.
Mac OS X 10.11.6 Safari 11.1.1Regards
Thanks for sharing your thoughts about 微信小程序.
Mac OS X 10.11.6 Google Chrome 67.0.3396.87Regards