Fer van Rijswijk
Fer van Rijswijk

Reputation: 159

kineticjs - createImageRegion for pixels with opacity > 0 not only 1

So the createImageRegion method ignores all pixels with a tiny bit of alpha/opacity.

How can you make this function so that also pixels with an opacity of .5 or something will be count for hitdetection?

I looked into KineticJS. A colorKey is added to a hitregion, but it transforms the key to a hex key with no alpha. I can't figure out a way how i could make this work.

Help is much appriciated!

this is where the magic happens. But i don't understand how i can include pixels whith any kind of transpanacy but 0

createImageHitRegion: function (callback) {
    var canvas = new Kinetic.Canvas(this.attrs.width, this.attrs.height);
    var context = canvas.getContext();
    context.drawImage(this.attrs.image, 0, 0);
    try {
        var imageData = context.getImageData(0, 0, canvas.getWidth(), canvas.getHeight());
        var data = imageData.data;
        var rgbColorKey = Kinetic.Type._hexToRgb(this.colorKey);
        // replace non transparent pixels with color key
        for (var i = 0, n = data.length; i < n; i += 4) {
            data[i] = rgbColorKey.r;
            data[i + 1] = rgbColorKey.g;
            data[i + 2] = rgbColorKey.b;
            // i+3 is alpha (the fourth element)
        }

        var that = this;
        Kinetic.Type._getImage(imageData, function (imageObj) {
            that.imageHitRegion = imageObj;
            if (callback) {
                callback();
            }
        });
    }
    catch (e) {
        Kinetic.Global.warn('Unable to create image hit region. ' + e.message);
    }
}

When i include: data[i + 3] = 255 (rgbColorKey.a) does not excist, none of the imageevents are working anymore

Upvotes: 3

Views: 632

Answers (1)

Fer van Rijswijk
Fer van Rijswijk

Reputation: 159

I found the answer:

       for (var i = 0, n = data.length; i < n; i += 4) {
            data[i] = rgbColorKey.r;
            data[i + 1] = rgbColorKey.g;
            data[i + 2] = rgbColorKey.b;
            if (!ignoreAlpha && data[i + 3] > 0) {
                data[i + 3] = 255;
            }
        }

This way, every pixel which has a bit of transparancy left, it will get a full color. So if you prototype this to kinetixJS it should work:

Kinetic.Image.prototype.createImageHitRegion = function (callback, ignoreTransparantPixels) {
var canvas = new Kinetic.Canvas(this.attrs.width, this.attrs.height);
var context = canvas.getContext();
var _ignoreTransparantPixels;
if(typeof ignoreTransparantPixels == 'undefined'){
    _ignoreTransparantPixels = false;
}

context.drawImage(this.attrs.image, 0, 0);

try {
    var imageData = context.getImageData(0, 0, canvas.getWidth(), canvas.getHeight());
    var data = imageData.data;

    var rgbColorKey = Kinetic.Type._hexToRgb(this.colorKey);
    // replace non transparent pixels with color key
    for (var i = 0, n = data.length; i < n; i += 4) {
        data[i] = rgbColorKey.r;
        data[i + 1] = rgbColorKey.g;
        data[i + 2] = rgbColorKey.b;
        if (!_ignoreTransparantPixels && data[i + 3] > 0) {
            data[i + 3] = 255;
        }

        //trace(data[i + 3]);
        // i+3 is alpha (the fourth element)
    }

    var that = this;
    Kinetic.Type._getImage(imageData, function (imageObj) {
        that.imageHitRegion = imageObj;
        if (callback) {
            callback();
        }
    });
}
catch (e) {
    Kinetic.Global.warn('Unable to create image hit region. ' + e.message);
}

}

Upvotes: 2

Related Questions