手记

hidpi-canvas-polyfill 绘制高清图片

作者:娇娇jojo

时间:2018年6月13日

到公司那么久,时间接触最长的组件是 canvas,没想到 canvas 的坑踩之不尽。前段时间恰好做了一活动,需要在 canvas 上绘制图片,但老生常谈的问题出现了:绘制后生成的图片模糊了!!! WTF ?别着急别着急,用 hidpi-canvas-polyfill 就能解决啦。

一、安装

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

或者:

bower install hidpi-canvas


二、原理

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

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


三、使用

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

// 获取设备像素比
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 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);			
    }		
}


// 绘制图片
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 上也会很清晰,就不举例了,大家自行去尝试~







0人推荐
随时随地看视频
慕课网APP