Jump to content

Phaser 3 texture getPixels (plural)


fazz
 Share

Recommended Posts

Hi all,

I have been unable to find a method to get all the pixel data from a cached image / texture in Phaser 3. Is anyone aware of a way?

I am aware of the textures.getPixel method https://photonstorm.github.io/phaser3-docs/Phaser.Textures.TextureManager.html#getPixel__anchor but this is only a single pixel method, is incredibly inefficient / slow when iterating across a whole image.

There were a number of ways to get all the image pixel data in Phaser 2 in one go; you could use getPixels from a renderTexture or a bitmapData.context. There is no such method in Phaser3 renderTexture, and there is no bitmapData any more.

Any help will be greatly appreciated!

Thanks

Link to comment
Share on other sites

If you look at the source of getPixel (https://github.com/photonstorm/phaser/tree/v3.12.0/src/textures/TextureManager.js#L907) it seems trivial to add getPixels.

All you need to do is make sure this line gets called with x,y,width,height:

var rgb = ctx.getImageData(0, 0, 1, 1);
 

Not a user of Phaser 3 yet, so maybe Rich has a more obvious solution.

Link to comment
Share on other sites

Thanks @Milton, @rich. It wasn't quite as trivial as I'd hoped, so I've probably gone around the houses with my solution. In case anyone's interested, I added the following method to the TextureManager to provide getPixels functionality.

   /**
     * Given a Texture this method will return an Object containing w, h and Uint8ClampedArray
     * of pixel data at the location in the Texture.
     *
     * @param {string} key - The unique string-based key of the Texture.
     * @param {(string|integer)} frame - The string or index of the Frame.
     *
     * @return An object populated with the w, h and Uint8ClampedArray of pixel values of the requested texture
     * or `null` if not found were out of bounds.
     */
    game.textures.getPixelsData = function(key, frame) {

        let textureFrame = this.getFrame(key, frame);

        if (textureFrame) {

            let w = textureFrame.width;
            let h = textureFrame.height;

            // have to create new as _tempCanvas is only 1x1
            let cnv = this.createCanvas('temp', w, h); // CONST.CANVAS, true);
            let ctx = cnv.getContext('2d');

            ctx.clearRect(0, 0, w, h);
            ctx.drawImage(textureFrame.source.image, 0, 0, w, h, 0, 0, w, h);

//            cnv.destroy();

            let rv = ctx.getImageData(0, 0, w, h);

            // add handy little method for converting specific pixel to Color object
            rv.getColorAt = function(x, y) {
                return new Phaser.Display.Color(
                    this.data[(x+y*this.width)*4],
                    this.data[(x+y*this.width)*4+1],
                    this.data[(x+y*this.width)*4+2],
                    this.data[(x+y*this.width)*4+3]
                );
            };

            return rv;
        }

        return null;
    };

And it can be used in the following way.

// get all pixel data for cached image
let data = this.textures.getPixelsData('myImage');

// get colour of pixel at x = 3, y = 2
let col = data.getColorAt(3, 2)

This is significantly faster than repeatedly calling this.textures.getPixel(3, 2, 'myImage') but I'm sure it could be optimised further.

Thanks for the help!

Link to comment
Share on other sites

12 minutes ago, rich said:

This is a lot easier :)


var src = this.textures.get('imageName').getSourceImage();

var canvas = this.textures.createCanvas('canvasName', src.width, src.height);

canvas.draw(0, 0, src);

//  You can now access the CanvasTexture properties, such as canvas.imageData to get all the pixels.

 

I don't see any difference.
And fazz's getPixels is a lot more consistent.
Makes sense to just have it in TextureManager.

Link to comment
Share on other sites

  • 3 years later...
On 9/28/2018 at 6:23 PM, rich said:

This is a lot easier :)

var src = this.textures.get('imageName').getSourceImage();

var canvas = this.textures.createCanvas('canvasName', src.width, src.height);

canvas.draw(0, 0, src);

//  You can now access the CanvasTexture properties, such as canvas.imageData to get all the pixels.

 

Hello 

Old Post / up up up :)

https://phaser.io/examples/v3/view/game-objects/render-texture/erase-part-of-render-texture-canvas

How to have the percentage revealed starting from this example?

 

Thks

Crazy

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...