0

I am trying to achieve realtime color changes to a PNG image using HTML5 and Canvas for an app I've been working on. I have researched two ways of achieving this that do not require altering each pixel as that is too expensive of an operation to be done every frame, but both methods have undesired consequences.

Method 1: Draw the original image to a temporary canvas, set the context's globalCompositeOperation to "source-in", and then draw a filled rectangle of the desired color to the temporary canvas (on top of the image), then return the newly tinted canvas/image for use in the main project. Source code of this approach can be found in answer #2 of: stackoverflow.com/questions/16228048/replace-a-specific-color-by-another-in-an-image-sprite-in-a-html5-canvas.

The problem with Method 1 is that none of the grayscale or darker components of the source image will carry over, only the alpha components and the new color. So, if I draw the tinted image repeatedly in the same spot, it will eventually be a solid color even if the original had some textured components that should remain a darker shade at all times. It works great for images that need to only be a single color with no texture.

Method 2: Separate the original image into RGB and black/transparent components and store each as a separate image. Then, use the 'lighten' mode to draw each of the components on top of one another. This is explained in depth with code snippets at: www.playmycode.com/blog/2011/06/realtime-image-tinting-on-html5-canvas/.

The problem with Method 2 is that any semi-transparent pixels get darker instead of remaining light and transparent as they should. It seems the Method 2 approach is used in some engines like Cocos2dx HTML but when I try on my own it always makes the transparent pixels darker.

The example image I used for testing is: https://i.stack.imgur.com/vrjl7.png

Here is an illustration of the methods and my intended result. https://i.stack.imgur.com/MWP8h.png

Sam J
  • 25
  • 2
  • 3
  • The approach described in the 'possible duplicate' behaves identically to Method 1 in my question. If you have an image with different shades of a color (such as [this gradient](http://i.imgur.com/wiDSGSi.png)) and try to tint the image with globalAlpha set to 1.0, the result will still be just a single solid color (red in that example). If you set the globalAlpha to a lower value, such as 0.5 in that example, the shades remain to an extent but it is not a true tint and is instead washed out as explained in the tutorial link on Method 2 above. – Sam J Oct 06 '13 at 17:20
  • For method 2, maybe each of the r,g,b image must handle transparency, so they are r+a / g+a / b+a images. OR you clear non-opaque pixels from those 3 layers. – GameAlchemist Oct 07 '13 at 02:11

0 Answers0