Canvas 在高清屏下绘制图片变模糊的解决方法


 

问题:

用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的值是多少,统一将canvasDOM节点的width属性设置为其csswidth属性的两倍,同理将height属性也设置为cssheight属性的两倍,即:

<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
// );

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM