javascript - Drawing to canvas always has blurry results -
i have searched many web pages , throughout stackoverflow , have not yet found answer problem. want make simple tile editor require me able edit canvas pixel pixel. each tile 8px 8px. have html properties , css use 8 8 pixels. have tried below method , have tried other various methods including html2canvas. blurry results. here test code reproduces problem.
i testing chromebook (toshiba chromebook 2) on latest stable release. have tested nexus 7 (2013) tablet , lg g3 android cell phone same results. using chrome browser on each device.
<!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 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>
updated code 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 + "," + + ")"; ctx.fillrect(x, y, 1, 1); } }); </script> </head> <body> <canvas id="canvas0" width="8" height="8" style="width:8px;height:8px;"></canvas> </body> </html>
you should rewrite drawpixel method draw pixel. there no need use imagedata objects here, , transforms doesn't work in case.
my suggestion (preserving signature):
function drawpixel (canvasname, x, y, r, g, b, a) { // these should in parent or global scope, pass in context var canvas = document.getelementbyid(canvasname); var ctx = canvas.getcontext("2d"); // set color, note alpha here value in range [0, 1] ctx.fillstyle = "rgba(" + r + "," + g + "," + b + "," + (a / 255) + ")"; ctx.fillrect(x, y, 1, 1); }
to make pixel sharper, use translate (and once) in global scope, example (a non-signature compatible version):
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); // show more drawpixel(ctx, 0, 3, 255, 0, 0, 255); drawpixel(ctx, 0, 4, 255, 0, 0, 255); // show image 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>
additionally, can remove style attribute inside tag. canvas element adopt size given width/height.
Comments
Post a Comment