hidpi-canvas-polyfill 绘制高清图片

canvas 的坑踩之不尽。比如:需要在 canvas 上绘制图片,但老生常谈的问题出现了:绘制后生成的图片模糊了!!! WTF ?别着急别着急,用 hidpi-canvas-polyfill 就能解决啦。

一、安装

1
<script src=".../dist/hidpi-canvas.min.js"></script>

或者:

1
bower install hidpi-canvas

 

二、原理

在 window 中有一个 devicePixelRatio 的属性,类似的,在 canvas context 中也存在一个BackingStorePixelRatio 的属性,该属性的值决定了浏览器在渲染 canvas 之前会用几个像素来来存储画布信息。如果 BackingStorePixelRatio 值是2,将一张100x100像素的图片绘制到浏览器中,该图片首先会在内存中生成一张200x200的图片,然后浏览器渲染的时候,会按100x100的图片来渲染,因此就变成了200x200,正好和内存中的图片大小一致,因此不会出现失真的问题。

那我们怎样让所有手机都不失真呢?我们可以根据 devicePixelRatio 与 BackingStorePixelRatio 的比值来决定canvas绘制时的坐标和大小。对应的canvas画布大小也要根据比值来设置。

 

三、使用

使用起来其实也很简单,下面举一个栗子(在 canvas 上绘制2张图片):

1
2
3
4
5
6
7
8
9
10
// 获取设备像素比
var getPixelRatio = function(context) {    
    var backingStore = context.backingStorePixelRatio ||
              context.webkitBackingStorePixelRatio ||
              context.mozBackingStorePixelRatio ||
              context.msBackingStorePixelRatio ||
              context.oBackingStorePixelRatio ||
              context.backingStorePixelRatio || 1;    
  return (window.devicePixelRatio || 1) / backingStore;
};

 

1
2
3
4
5
6
7
8
9
10
11
12
13
var canvas = document.getElementById("canvas"); 
var ctx = canvas.getContext('2d');
 
// 加载图片
var img1 = new Image();    
img1.src = "img/1.png";      
img1.onload = function() {          
    var img2 = new Image();                
    img2.src = "img/2.png";          
    img2.onload = function() {              
        drawImg(ctx, getPixelRatio, img1, img2);        
    }      
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 绘制图片
function drawImg(ctx, ratio, image1, image2){
    // 对图片先缩小再放大
    var swidth1 = image1.width;     
    var sheight1 = image1.height;       
    var width1 = 0.5 * swidth1;       
    var height1 = 0.5 * sheight1;     
    var img1Width = width1 * ratio;       
    var img1Height = height1 * ratio; 
     
    // 第二张图片的大小必须依据第一张图片的尺寸来(比如第一张图片的 width 是526,height 是1112),不然展示出来的图片大小就不对
    var swidth2 = img1Width * 484 / 526;    
    var sheight2 = img1Height * 768 / 1112;     
    var img2Left = img1Width * 25 / 526;    
    var img2Top = img1Height * 172 / 1112; 
     
    // 绘制图片
    ctx.drawImage(image1, 0, 0, img1Width, img1Height);
    ctx.drawImage(image2, img2Left, img2Top, swidth2, sheight2);
     
    // 生成 base64 的图片                                
    var img = new Image();     
    img.src = canvas.toDataURL('image/jpeg', 0.5); // 压缩图片,默认压缩比是0.5                  
    $("body").prepend(img);
}

 

对应的这样处理之后,文字绘制在 canvas 上也会很清晰,就不举例了,大家自行去尝试~

posted @ 2020-09-09 11:08  MamBa_20  阅读(603)  评论(0)    收藏  举报