canvas调用ctx.drawImage放大绘制瓦片集时边缘出现多余黑线问题
问题根源
你遇到的边缘黑线问题是Canvas默认的图像平滑插值机制导致的:当你放大绘制裁剪的瓦片区域时,默认启用的双线性插值算法会采样裁剪边界外1px范围内的像素做平滑计算,你裁剪的16x16瓦片边缘刚好紧挨着1px的黑色分隔线,插值后就会把黑色像素混入绘制结果,出现边缘黑线。
可用解决方案
方案1:关闭图像平滑(像素瓦片首选)
对于像素风格的瓦片集,直接关闭Canvas的图像平滑功能即可,放大后会保留锐利的像素边缘,不会采样相邻区域的内容:
在绘制前添加一行代码:
ctx.imageSmoothingEnabled = false; // 兼容不同浏览器前缀可选添加 ctx.webkitImageSmoothingEnabled = false; ctx.msImageSmoothingEnabled = false;
修改后的核心绘制逻辑示例:
var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); // 全局关闭图像平滑 ctx.imageSmoothingEnabled = false; function draw() { var img = new Image(); img.onload = function() { let tileSize = 16; let offset = 0; for (var y = 0; y < 2; y++) { for (var x = 0; x < 2; x++) { ctx.drawImage(img, 1, 1, 16, 16, x*tileSize+offset, y*tileSize+offset, tileSize, tileSize); } } tileSize = 64; offset = 100; for (var y = 0; y < 2; y++) { for (var x = 0; x < 2; x++) { ctx.drawImage(img, 1, 1, 16, 16, x*tileSize+offset, y*tileSize+offset, tileSize, tileSize); } } }; img.src = 'https://i.imgur.com/sW6m5kr.jpg'; } draw();
<canvas id="canvas" height="900" width="900"></canvas>
方案2:收缩裁剪范围(需要保留平滑效果时用)
如果你的场景需要保留图像平滑效果,可以把裁剪区域往内收缩0.5px,避开插值采样的边缘范围:
把原来的裁剪参数sx=1, sy=1, sWidth=16, sHeight=16改成sx=1.5, sy=1.5, sWidth=15, sHeight=15即可,这样采样范围完全在瓦片内部,不会触碰到外面的黑线。
方案3:预处理瓦片集
如果需要长期使用该瓦片集,建议修改瓦片集的分割规则:去掉黑色分隔线,给每个瓦片添加1px的边缘重复像素作为padding,就算插值采样到边界也只会采样到和瓦片边缘相同的像素,不会出现杂色。
内容的提问来源于stack exchange,提问作者ReaperSoon
相关产品推荐
相关产品推荐

