Jump to content

Phaser 3 texture getPixels (plural)


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 post
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 post
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 post
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 post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...