2015-04-01 14 views
0

我已經搜索了很多網頁和整個Stackoverflow,並且還沒有找到我的問題的答案。我想製作一個簡單的拼貼編輯器,這將需要我能夠逐個像素地編輯畫布。每個瓦片將是8px乘8px。我有我的HTML屬性和CSS使用8乘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> 

更新的代碼BELOW

<!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> 

回答

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>

此外,您可以刪除標籤內的樣式屬性。 canvas元素將採用寬度/高度給定的大小。

+0

謝謝。我不知道把它放在全球範圍內。我已經更改了我的代碼以匹配您提供的內容,並修復了'b'後缺少的'+'。結果是一樣的。爲了清楚起見,我已經將新代碼添加到了我的問題中。 – Nicksen782 2015-04-01 05:32:40

+0

@ Nicksen782 ops,我的翻譯不好。這適用於線條,但fillRect最好不要使用它。新增現場演示 - 現在看起來很犀利 – K3N 2015-04-01 05:39:15

+0

我添加了一個圖片鏈接,因爲我還無法上傳圖片。我評論了翻譯線。結果更清晰但不像像素那樣塊狀。 – Nicksen782 2015-04-01 05:45:53