前言
说明:本文省略部分非关键代码,麻烦自己补全。
一般情况,在高清屏的设备下,任何绘制canvas中的图像、文字、线条、形状都可能会出现模糊的问题。可通过引入 GitHub 中的 hidpi-canvas 有效地解决。
正文
- 首先去 GitHub 下载 hidpi-canvas.js 文件:传送门;
- 在项目中引入 hidpi-canvas.js 文件;
- 调用 getPixelRatio( ) 函数,得到 ratio 值;
- 在 drawImage( ) 中,将 width 和 height 乘以 ratio;
- 效果如下,但抱歉,没做对比图!
在部分 iOS 设备中,可能会存在 image.onload 失效的问题,会导致无法将图片画到 canvas 中。引起该现象的原因可能是:
1、iOS中存在 image.onload 失效的问题(注意:image.onload 执行的前提是图片正常加载完成,如果稍微出错,就会执行 image.onerror 而不是 image.onload);
2、如果 image.src 是 base64 格式文件,不要设置 image.crossOrigin = "anonymous",可能会出现 image.onload 无法执行的问题,从而无法正常画图。
关于 onload 失效的问题,看 Stack Overflow 这个解答,可能收获挺多的:IPhone img onload fails。
// html <div onclick="makeCanvasToPhoto()" style="width: 100px; padding: 10px 30px;background: #eee;text-align: center">生成图片</div> <canvas id="canvasBox" style="margin: 50px auto"></canvas> <!-- 引入js --> <script type="text/javascript" src="canvas.js"></script> <script type="text/javascript" src="hidpi-canvas.min.js"></script> // canvas.js 文件 function makeCanvasToPhoto() { var that = this; var canvas = document.getElementById("canvasBox"); var context = canvas.getContext('2d'); var ratio = getPixelRatio(context); // 关键代码 canvas.width = 300 * ratio; // 画布宽度 canvas.height = 300 * ratio; // 画布高度 var divWidth = 300 * ratio; // 用于内容居中 var divHeight = 300 * ratio; // 用于内容居中 // 画矩形 context.beginPath(); context.fillStyle = "#abcdef"; context.fillRect(0, 0, divWidth, divHeight); context.closePath(); // 图片 context.beginPath(); var imgObj = new Image(); imgObj.crossOrigin = "anonymous"; // 在iOS 9设备中,如果src是base64格式,设置了crossOrigin 属性,会导致无法执行image.onload 而执行image.onerror 函数 imgObj.src = 'http://img0.imgtn.bdimg.com/it/u=458129248,1588126214&fm=26&gp=0.jpg'; imgObj.onload = function () { var imgWidth = '150'; var imgHeight = '150'; context.drawImage(this, 50, 50, imgWidth * ratio, imgHeight * ratio) }; context.closePath(); // 文本 context.beginPath(); context.font = '32px bold'; context.fillStyle = '#1a1a1a'; context.textAlign = 'center'; context.textBaseline = 'middle'; context.fillText('文本', 50, 240); context.closePath(); context.drawImage(canvas, 0, 0, divWidth, divHeight); var base64Obj = canvas.toDataURL('image/png', 1); console.log(base64Obj); } function getPixelRatio(context) { var backingStore = context.backingStorePixelRatio || context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1; return (window.devicePixelRatio || 1) / backingStore; };
效果如图:
效果图