Canvas 生成图片模糊的解决方案
说明:本文省略部分非关键代码,麻烦自己补全。
一般情况,在高清屏的设备下,任何绘制 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 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() { const canvas = document.getElementById('canvasBox') const context = canvas.getContext('2d') const ratio = getPixelRatio(context) // 关键代码 canvas.width = 300 * ratio // 画布宽度 canvas.height = 300 * ratio // 画布高度 const divWidth = 300 * ratio // 用于内容居中 const divHeight = 300 * ratio // 用于内容居中 // 画矩形 context.beginPath() context.fillStyle = '#abcdef' context.fillRect(0, 0, divWidth, divHeight) context.closePath() // 图片 context.beginPath() const 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 () { const imgWidth = '150' const 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) const base64Obj = canvas.toDataURL('image/png', 1) console.log(base64Obj) } function getPixelRatio(context) { const backingStore = context.backingStorePixelRatio || context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1 return (window.devicePixelRatio || 1) / backingStore }
效果如图:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论