Reputation: 11603
I have a static image (a png) that I'm drawing on a canvas element using drawImage
.
var _canvas = null;
var _context = null;
var _curImageData;
function copyImageToCanvas(aImg)
{
_canvas = document.getElementById("canvas");
var w = aImg.naturalWidth;
var h = aImg.naturalHeight;
_canvas.width = w;
_canvas.height = h;
_context = _canvas.getContext("2d");
_context.clearRect(0, 0, w, h);
_context.drawImage(aImg, 0, 0);
_curImageData = _context.getImageData(0, 0, w, h);
}
I then manipulate the image data pixel by pixel (setting the opacity to 255 or 0 depending on the pixel value) and then update the canvas using putImageData
.
function updateImage(maxPixelValToShow)
{
for (var x = 0; x < _curImageData.width; x++)
for (var y = 0; y < _curImageData.height; y++)
{
var offset = (y * _curImageData.width + x) * 4;
var r = _curImageData.data[offset];
var g = _curImageData.data[offset + 1];
var b = _curImageData.data[offset + 2];
var a = _curImageData.data[offset + 3];
var pixelNum = ((g * 255) + b);
//if greater than max or black/no data
if (pixelNum > maxPixelValToShow || (!r && !g && !b)) {
_curImageData.data[offset + 3] = 0;
} else {
_curImageData.data[offset + 3] = 255;
}
}
_context.putImageData(_curImageData, 0, 0);
}
And this all works perfectly. The issue I'm having is when I create a canvas twice the size of my image (or half the size, for that matter) and draw the image to fit the canvas size.
function copyImageToCanvas(aImg)
{
_canvas = document.getElementById("canvas");
var w = aImg.naturalWidth * 2; //double the size!
var h = aImg.naturalHeight * 2; //double the size!
_canvas.width = w;
_canvas.height = h;
_context = _canvas.getContext("2d");
_context.clearRect(0, 0, w, h);
_context.drawImage(aImg, 0, 0, w, h);
_curImageData = _context.getImageData(0, 0, w, h);
}
I'm getting lots of strange artifacts around the edges of my image when I call my updateImage
function. Does anyone know a) why this is happening and b) what can I do about it?
Here are some images to show what is being generated:
The original image after my updateImage
function call
The resized image after my updateImage
function call
[Solution] Thanks Adam and sunetos, that was the problem. It worked fine once I setup one canvas to store the original file data and do the pixel manipulation and another only for display. Code snippet below:
function updateImage(maxPixelValToShow) {
//manipulate the _workingContext data
_workingContext.putImageData(_curImageData, 0, 0);
_displayContext.clearRect(0, 0, _workingCanvas.width*_scale, _workingCanvas.height*_scale);
_displayContext.drawImage(_workingCanvas, 0, 0, _workingCanvas.width*_scale, _workingCanvas.height*_scale);
}
Upvotes: 1
Views: 7108
Reputation: 3508
It looks like the image smoothing used by the browser when scaling up the image in drawImage() antialiased the edges of your shape, causing new intermediate color values around the edge that are not handled by your updateImage() function. Like Adam commented, you should apply your updateImage() logic against the unmodified original pixels, and then scale it.
Upvotes: 1