问题:
用canvas绘制图片的时候会模糊,但是用img显示的时候就不会,canvas和img的大小是相同的
至于为什么会变模糊,这和浏览器处理 canvas 的方式有关,相关的文章可以参考这篇 High DPI Canvas,这里不作深入介绍。
https://www.npmjs.com/package/hidpi-canvas
<!-- 通过 img 标签引入图片,以便绘制到 canvas 中 --> <img src="html5rocks.png" alt="" width="300" height="90">
<!-- canvas --> <canvas width="300" height="90"></canvas> <script> function init() { var canvas = document.querySelector('canvas'); var ctx = canvas.getContext('2d'); ctx.drawImage(document.querySelector('img'), 0, 0, 300, 90); } window.onload = init; </script>
解决问题:
首先,引入 hidpi-canvas
其实,不只是绘制图片时会出现模糊的问题,正常情况下,在高清屏的设备下,任何绘制canvas中的图形(包括文字)都会出现模糊的问题。上面这个就是为了解决这个问题,但是他没有处理图片。
接下来,修改绘制图片的代码
将 init 含税修改成下面的代码
function init() { var canvas = document.querySelector('canvas'); var ctx = canvas.getContext('2d'); // polyfill 提供了这个方法用来获取设备的 pixel ratio var getPixelRatio = function(context) { var backingStore = context.backingStorePixelRatio || context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1; return (window.devicePixelRatio || 1) / backingStore; }; var ratio = getPixelRatio(ctx); // 注意,这里的 width 和 height 变成了 width * ratio 和 height * ratio ctx.drawImage(document.querySelector('img'), 0, 0, 300 * ratio, 90 * ratio); }
这个解决方案本质上是:
不管当前的devicePixelRatio
的值是多少,统一将canvas
DOM节点的width属性设置为其css
width属性的两倍,同理将height属性也设置为css
height属性的两倍,即:
<canvas width="320" height="180" style="width:160px;height:90px;"></canvas>
这样整个 canvas 的坐标系范围就扩大为两倍,但是在浏览器的显示大小没有变,canvas画图的时候,按照扩大化的坐系来显示,不清晰的问题就得以改善了
测试成功:母亲节H5小游戏
https://act.mcake.com/fangli/2022/wap/motherDay-h5/index.html
<canvas id="myCanvas" width="750" height="1333"></canvas> <script src="scripts/hidpi-canvas.js"></script> <script src="scripts/canvas.js"></script>
canvas.js 绘制海报
/*绘制照片*/
function drawAndShareImage(windW,windH,canvasImg, imgArr,num,textT,textL){
var canvas=document.getElementById("myCanvas");
//var canvas = document.createElement("myCanvas");
canvas.width = windW;
canvas.height = windH;
var context = canvas.getContext("2d");
var getPixelRatio = function(context) {
var backingStore = context.backingStorePixelRatio ||
context.webkitBackingStorePixelRatio ||
context.mozBackingStorePixelRatio ||
context.msBackingStorePixelRatio ||
context.oBackingStorePixelRatio ||
context.backingStorePixelRatio || 1;
return (window.devicePixelRatio || 1) / backingStore;
};
var ratio = getPixelRatio(context);
context.rect(0 , 0 , canvas.width*ratio , canvas.height*ratio);
context.fillStyle = "#743700";
context.fill();
var myImage = new Image();
myImage.src = canvasImg.src; //背景图片 你自己本地的图片或者在线图片
myImage.crossOrigin = 'Anonymous';
myImage.onload = function(){
//绘制背景图
context.drawImage(myImage , 0 , 0 , windW*ratio , windH*ratio);
//绘制文字
context.font = "22px Courier New";
context.fillText(num,textL,textT+15);
var imglist = [];
var item = {}
var base64 = ""
var img = ""
$.each(imgArr, function(index,item){
imglist[index] = new Image();
imglist[index].src = item.src; //你自己本地的图片或者在线图片
imglist[index].crossOrigin = 'Anonymous';
imglist[index].onload = function(){
context.drawImage(imglist[index] ,item.offsetLeft*ratio, item.offsetTop*ratio, item.with*ratio, item.height*ratio);
base64 = canvas.toDataURL("image/png");
img = document.getElementById('myCanvas');
img.setAttribute('src' , base64);
$(".downImg").attr("src",base64);
}
})
}
}
// drawAndShareImage(
// windW,
// windH,
// {
// with:windW,
// height:windH,
// src:"images/down-img-bg.png"
// },photoArr, 6,textT,textL
// );