绘制到画布总是有模糊的结果

时间:2015-04-01 05:10:21

标签: javascript html5-canvas

我搜索了许多网页和整个Stackoverflow,但还没有找到我的问题的答案。我想制作一个简单的平铺编辑器,这将要求我能够逐个像素地编辑画布。每个图块将为8px×8px。我有我的HTML属性和CSS使用8 x 8像素。我尝试了下面的方法,我尝试了其他各种方法,包括html2canvas。我总是得到模糊的结果。这是一些重现此问题的测试代码。

Image

我正在使用最新稳定版本的Chromebook(东芝Chromebook 2)进行测试。我还测试了Nexus 7(2013)平板电脑和LG G3 Android手机都具有相同的效果。我在每台设备上使用Chrome浏览器。

<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>test</title>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
    <style>
    body {background:white;}
    </style>
    <script>
    $(document).ready(function() {

        drawPixel('canvas0', 0, 0, 255, 0, 0, 255);
        drawPixel('canvas0', 0, 1, 255, 0, 0, 255);
        drawPixel('canvas0', 0, 2, 255, 0, 0, 255);
        drawPixel('canvas0', 0, 3, 255, 0, 0, 255);
        drawPixel('canvas0', 0, 4, 255, 0, 0, 255);

        function drawPixel (canvasname, x, y, r, g, b, a) {
            // console.log('values passed to drawPixel:', canvas, x, y, r, g, b, a);
            var canvas = document.getElementById(canvasname);
            var canvasWidth = canvas.width;
            var canvasHeight = canvas.height;
            var ctx = canvas.getContext("2d");
            ctx.translate(0.5, 0.5) ;
            var canvasData = ctx.getImageData(0, 0, canvasWidth, canvasHeight);

            var index = ((x + y) * canvasWidth) * 4;
            console.log('1',canvasData);
            canvasData.data[index + 0] = r;
            canvasData.data[index + 1] = g;
            canvasData.data[index + 2] = b;
            canvasData.data[index + 3] = a;
            console.log('2',canvasData);

            ctx.putImageData(canvasData, 0, 0);
        }
    });
    </script>
</head>

<body>
<canvas id="canvas0" width="8" height="8" style="width:8px;height:8px;"></canvas>

</body>

</html>

以下更新代码

<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>test</title>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
    <style>
    body {background:white;}
    </style>
    <script>
    $(document).ready(function() {
        var canvas = document.getElementById('canvas0');
        var ctx = canvas.getContext("2d");
        ctx.translate(0.5, 0.5);

        drawPixel(ctx, 0, 0, 255, 0, 0, 255);
        drawPixel(ctx, 0, 1, 255, 0, 0, 255);
        drawPixel(ctx, 0, 2, 255, 0, 0, 255);
        drawPixel(ctx, 0, 3, 255, 0, 0, 255);
        drawPixel(ctx, 0, 4, 255, 0, 0, 255);

        function drawPixel(ctx, x, y, r, g, b, a) {
            ctx.fillStyle = "rgba(" + r + "," + g + "," + b  + "," + a + ")";
            ctx.fillRect(x, y, 1, 1);
        }
    });
    </script>
</head>

<body>
<canvas id="canvas0" width="8" height="8" style="width:8px;height:8px;"></canvas>

</body>

</html>

1 个答案:

答案 0 :(得分:0)

您应该重写drawPixel方法以仅绘制像素。这里不需要使用ImageData对象,并且在任何情况下转换都不适用。

我的建议是这样做(保留签名):

 function drawPixel (canvasname, x, y, r, g, b, a) {
     // these should in parent or global scope, just pass in the context
     var canvas = document.getElementById(canvasname);
     var ctx = canvas.getContext("2d");

     // set color, note alpha here is a value in the range [0, 1]
     ctx.fillStyle = "rgba(" + r + "," + g + "," + b + "," + (a / 255) + ")";
     ctx.fillRect(x, y, 1, 1);
}

要使像素更清晰,请在全局范围内使用translate(并且只使用一次),例如(非签名兼容版本):

var canvas = document.getElementById("test");
var ctx = canvas.getContext("2d");

drawPixel(ctx, 0, 0, 255, 0, 0, 255);
drawPixel(ctx, 0, 1, 255, 0, 0, 255);
drawPixel(ctx, 0, 2, 0, 255, 0, 255); // to show more clearly
drawPixel(ctx, 0, 3, 255, 0, 0, 255);
drawPixel(ctx, 0, 4, 255, 0, 0, 255);

// show image with standard interpolation (bilinear)
ctx.drawImage(canvas, 0, 0, 8, 8,   8, 0, 64, 64);

// show image enlarged using nearest-neighbor
ctx.imageSmoothingEnabled = false;
ctx.mozImageSmoothingEnabled = false;
ctx.webkitImageSmoothingEnabled = false;

ctx.drawImage(canvas, 0, 0, 8, 8,   50, 0, 64, 64);

function drawPixel(ctx, x, y, r, g, b, a) {
  ctx.fillStyle = "rgba(" + r + "," + g + "," + b + "," + (a / 255) + ")";
  ctx.fillRect(x, y, 1, 1);
}
<canvas id="test" width=130 height=64></canvas>

此外,您可以删除标记内的style属性。 canvas元素将采用宽度/高度给出的大小。