fazz Posted September 23, 2018 Share Posted September 23, 2018 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 More sharing options...
Milton Posted September 23, 2018 Share Posted September 23, 2018 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. fazz 1 Link to comment Share on other sites More sharing options...
rich Posted September 23, 2018 Share Posted September 23, 2018 Use a CanvasTexture. It has a pixels property, as well as an arrayBuffer and all the other things BitmapData had. fazz 1 Link to comment Share on other sites More sharing options...
fazz Posted September 23, 2018 Author Share Posted September 23, 2018 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 More sharing options...
rich Posted September 28, 2018 Share Posted September 28, 2018 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. Thecrazylegs 1 Link to comment Share on other sites More sharing options...
Milton Posted September 28, 2018 Share Posted September 28, 2018 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 More sharing options...
rich Posted September 28, 2018 Share Posted September 28, 2018 Each to their own. Link to comment Share on other sites More sharing options...
Thecrazylegs Posted January 27, 2022 Share Posted January 27, 2022 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 More sharing options...
Recommended Posts