Skip to content Skip to sidebar Skip to footer

Canvas Doesn't Draw Edge Correctly When Extract Image From Sprite Image

I tried to use ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight); API to extract image from a sprite image. But I found Canvas renders the edge from the adjace

Solution 1:

This is because of jpeg compression. You probably did set the quality parameter of toDataURL('image/jpeg', quality) to something else than the maximum and default1[edit: actually, as found out by OP, the default is .92]. By doing so, the jpeg algorithm will take bigger blocks of pixels to do its lossy compression. You can see that on your image, where the two rects do collide, there is some antialiasing artifacts.

The lower the compression, the bigger these artifacts will be :

// your original canvasvar canvas = document.createElement('canvas');
var _ctx = canvas.getContext('2d');
canvas.width = 800;
canvas.height = 400;
_ctx.fillStyle = 'white';
_ctx.fillRect(0, 0, 800, 400);
_ctx.fillStyle = 'red';
_ctx.fillRect(0, 0, 400, 400);
_ctx.fillStyle = 'green';
_ctx.fillRect(400, 100, 400, 200);


var img = document.createElement('img');
img.onload = function() {
  // lets zoom a little bit
  ctx.drawImage(this, 300, 0, 300, 300, 0, 0, 400, 400);
}
var ctx = document.getElementById('output').getContext('2d');

// since we do zoom the image, lets try to keep antialiasing as its minimum
ctx.webkitImageSmoothingEnabled =
  ctx.mozImageSmoothingEnabled =
  ctx.msImageSmoothingEnabled =
  ctx.imageSmoothingEnabled = false;

range.oninput = function() {
  img.src = canvas.toDataURL('image/jpeg', +this.value);
}
range.oninput();
<label>JPEG quality: <inputtype="range"id="range"min="0"max="1"step="0.01"value="1"></label><br><canvasid="output"height="400"></canvas>

JPEG is great for pictures, but with such images, you should stick to png, which will offer an lossless compression, and will even produce an smaller image size on this exact image :

var canvas = document.createElement('canvas');
var _ctx = canvas.getContext('2d');
canvas.width = 800;
canvas.height = 400;
_ctx.fillStyle = 'white';
_ctx.fillRect(0, 0, 800, 400);
_ctx.fillStyle = 'red';
_ctx.fillRect(0, 0, 400, 400);
_ctx.fillStyle = 'green';
_ctx.fillRect(400, 100, 400, 200);


var img = document.createElement('img');
img.onload = function() {
  // lets zoom even more
  ctx.drawImage(this, 300, 0, 200, 200, 0, 0, 400, 400);
}
var ctx = document.getElementById('output').getContext('2d');
ctx.webkitImageSmoothingEnabled =
  ctx.mozImageSmoothingEnabled =
  ctx.msImageSmoothingEnabled =
  ctx.imageSmoothingEnabled = false;
img.src = canvas.toDataURL('image/png');

canvas.toBlob(function(b){console.log('jpg_size', b.size)}, 'image/jpeg', .1);
canvas.toBlob(function(b){console.log('png_size', b.size)}, 'image/png');
<canvasid="output"height="400"></canvas>

Post a Comment for "Canvas Doesn't Draw Edge Correctly When Extract Image From Sprite Image"