views:

149

answers:

1

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

The original image after my updateImage function call

The resized image

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);
}
A: 

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.

sunetos