壹影博客.
我在下午4点钟开始想你
手机端绘制canvas模糊问题
  • 2022-4-29日
  • 0评论
  • 447围观

手机端绘制canvas模糊问题处理

一、关于canvas

(1)canvas绘制的是位图,而我们平常用的jpg,png也是位图。
位图又叫像素图或栅格图,它是通过记录图像中每一个点的颜色、深度等信息来存储和显示图像。具象一点讲,可以将位图想象成一个巨大的拼图,这个拼图有无数的拼块,每个拼块代表了一个纯色的像素点。理论上,1个位图像素对应着1个物理像素。

(2)canvas的width和height属性

<canvas width="600" height="300" style="width: 300px; height: 150px"></canvas>

style中的width和height分别代表canvas这个元素在界面上所占据的宽高,即样式上的宽高
attribute中的width和height则代表canvas实际像素的宽高
canvas默认的width和height是300 * 150,对其设置了css之后,canvas会根据设置css宽高进行缩放(注意不是裁剪)

二、手机端模糊原因

因为 canvas 不是矢量图,而是像图片一样是位图模式的。高 dpi 显示设备意味着每平方英寸有更多的像素。也就是说二倍屏,浏览器就会以2个像素点的宽度来渲染一个像素,该 canvas 在 Retina 屏幕下相当于占据了2倍的空间,相当于图片被放大了一倍,因此绘制出来的图片文字等会变模糊。

三、解决方案

(1)在浏览器的 window 对象中有一个 devicePixelRatio 的属性,该属性表示了屏幕的设备像素比,即用几个(通常是2个)像素点宽度来渲染1个像素。

       举例来说,假设 devicePixelRatio 的值为 2 ,一张 100×100 像素大小的图片,在 Retina 屏幕下,会用 2 个像素点的宽度去渲染图片的 1 个像素点,因此该图片在 Retina 屏幕上实际会占据 200×200 像素的空间,相当于图片被放大了一倍,因此图片会变得模糊。

var myCanvas = document.getElementById("my_canvas");
var context = myCanvas.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);
 
myCanvas.style.width = myCanvas.width + 'px';
myCanvas.style.height = myCanvas.height + 'px';
//或者在canvas的父元素上使用缩放,使用css3的 transform:scale(0.5,0.5)即可,意思为缩放到原来的2倍大小,和canvas放大两倍刚好抵消掉。
/*
#parent{
      transform:scale(0.5,0.5);//父元素缩小两倍
      zoom:0.5
   }
*/
 
myCanvas.width = myCanvas.width * ratio;
myCanvas.height = myCanvas.height * ratio;

(2)由于 Canvas 放大后,相应的绘制图片时也要放大,有两种方式:

//第一种:每一个绘制相应的放大
context.font = "36px Georgia"; //一倍屏下18px字体
context.fillStyle = "#999";
context.fillText("我是清晰的文字", 50*ratio, 50*ratio);// 坐标位置乘以像素比
//第二种:直接使用 scale 方法
// 放大倍数
context.scale(ratio, ratio);
 
context.font = "18px Georgia";
context.fillStyle = "#999";
context.fillText("我是清晰的文字", 50, 50);

 

发表评论