views:

47

answers:

1

Here is the code that works perfectly well in Firefox, but I just do not get why it does not work in Webkit browsers! Note: Im using jQuery to select the canvas element.

    (function()
    {
        flipV=function(imageData)
        {
            var n = new Array();
            var d = imageData.data;
        // loop through over row of pixels
            for (var row=0;row<imageData.height;row++)
            {
            // loop over every column
                for (var col=0;col<imageData.width;col++)
                {
                    var si,di,sp,dp;

                // source pixel
                    sp=(imageData.width*row)+col; 

                // destination pixel
                dp=(imageData.width*((imageData.height-1)-row))+col; 

                // source and destination indexes, will always reference the red pixel
                si=sp*4;
                    di=dp*4;

                    n[di]=d[si]; // red
                    n[di+1]=d[si+1]; // green
                    n[di+2]=d[si+2]; // blue
                    n[di+3]=d[si+3]; // alpha
                }
            }
            imageData.data=n;

            return imageData;
        };

        var imgs = ['/images/myimage.png'];

        var $c=$('#canvas');
        var cxt=$c[0].getContext('2d');


        var w=$c.width();
        var h=$c.height();

        var img1 = new Image();
        img1.onload=function()
        {   
            cxt.drawImage(img1,0,0,img1.width,img1.height,0,0,w,h);
            imageData = flipV(cxt.getImageData(0,0,w,h));
            cxt.putImageData(imageData,0,0)

        };
        img1.src=imgs[0];

    }
)();
+1  A: 

Edit: I played with this a little, and got it to work. The problem is when when you set imageData.data = n. It looks like Chrome/WebKit won't work with a different data array. To make it work, I passed the context object to flipV and called createImageData(imageData.width, imageData.height) to get a fresh ImageData object, set n = newImageData.data, and returned newImageData.

I'll leave the rest here for reference:

There is an easier and most likely faster way to flip an image though, that will work across domains. You can use the scale function to automatically flip everything anything you draw along the y axis. You just need to be sure to call save() and restore() and remember to adjust the location since everything is flipped.

function drawVFlipped(ctx, img) {
    ctx.save();
    // Multiply the y value by -1 to flip vertically
    ctx.scale(1, -1);
    // Start at (0, -height), which is now the bottom-left corner
    ctx.drawImage(img, 0, -img.height);
    ctx.restore();
}
Matthew Crumley
@Mathew Actually other filters I have that use getImageData(), such as grayscale or invert, work perfectly fine with local images. It seems to be just this one flipV filter that has a problem.I had tried the negative scaling before but had problems with an "INDEX_SIZE_ERR". Just realized it's because I'm using drawImage to also crop the source and was placing the - on the wrong height var.You are right that negative scaling is a much easier method than modifying imageData, tho I'd still like to know why my filter works in FF and not Webkit.
talentedmrjones
I had a feeling that that new array might have something to do with it. Thanks for experimenting and confirming! You are indeed correct that the negative scaling is a much better,easier,more elegant way of handling the flip, so I will just continue on with that method.
talentedmrjones