×

Discussion Board

Results 1 to 14 of 14
  1. #1
    Registered User
    Join Date
    Mar 2003
    Posts
    8

    Dynamically change the color of a PNG?

    Is it possible to dynamically change the color of a PNG image using Nokia's MIDP UI API during runtime? And if so, how?

    I guess one solution would be to manipulate the pixel data directly, after retrieving it using DirectGraphics' getPixels method. Now the question becomes, how do I manipulate the pixel data to, say, change all the white pixels to red? How about changing the color of a certain portion of the image (not necessarily rectangular in shape)?

    Cheers!

  2. #2
    Super Contributor
    Join Date
    Mar 2003
    Location
    Israel
    Posts
    2,280
    how do I manipulate the pixel data to, say, change all the white pixels to red?
    Code:
    if (pixel[i] == 0xffffffff) then pixel[i] = 0xffff0000
    Of course some pixels might be very close to white but not exactly white, and they won't be changed by this instruction. So you might want to change the condition to something like
    Code:
    if (Math.abs(pixel[i] - 0xffffffff) < aThreshold)
    How about changing the color of a certain portion of the image (not necessarily rectangular in shape)?
    That depends on the portion. You'll need a formula to determine if a certain pixel is in the area. For example if you want to change all the pixels in a circle of radius 10 with it's center in (30,30) to white then you could do:
    Code:
    if ((x - 30) * (y - 30) < 100) then pixel[x + y * width] = 0xffffffff
    shmoove

  3. #3
    Registered User
    Join Date
    Mar 2003
    Posts
    8
    shmoove, thanks! Works like a charm

    By the way, is there a place where I can find out which formats (TYPE_USHORT_4444_ARGB, TYPE_INT_8888_ARGB, etc.) are supported by the different phones?

    Cheers!

  4. #4
    Super Contributor
    Join Date
    Mar 2003
    Location
    Israel
    Posts
    2,280
    Don't know.

  5. #5
    Regular Contributor
    Join Date
    Aug 2003
    Posts
    134
    You can use Alpha blending as well.

    If you want a portion of the screen blend to red, just call fillTriangle() or so and set the colour's alpha bits.

    Also has an advantage: fully native.

    gr,

    Danny

  6. #6
    Registered User
    Join Date
    Mar 2003
    Posts
    8
    > dannyc4

    I'm not sure I understand what you mean. Would you mind explaining in more detail?

    Thanks.

  7. #7
    Regular Contributor
    Join Date
    Aug 2003
    Posts
    134
    Well, Shmoove described how to directly manipulate pixel colours. That way you, for example, can change the colour 0xF234 to 0xF67E if you like.

    What I mean is when you want an area on your display to blend to a specific colour, you can use alphablending. Alphablending lets you merge a pixel's colour with a new colour. The "weight" of the merge is given by the alpha value. The higher the value the more it blends to the new colour.

    For example, say you already have drawn your picture on Graphics and you want to make it half darker (more black), then overwrite all pixels to ARGB colour of 0x7000 (TYPE_USHORT_4444_ARGB).

    0x7000 means Alpha value is 7 out of 15. RGB colour value 0x000 means completely black. So the result is that the native DirectGraphics drawing code will merge the original pixels' colours with the black colour using half opacity.

    You can do the same for other colours, for example blending it to red in case you like some emergency flashes in your game, or blend it to blue when you are under water.

    You might use dg.fillPolygon(int[] xPoints, int xOffset, int[] yPoints, int yOffset, int nPoints, int argbColor) for example or fillTriangle for more complex shapes.

    gr,

    Danny

  8. #8
    Registered User
    Join Date
    Mar 2003
    Posts
    8
    > dannyc4:

    So what you're saying is, I can do this:

    <pseudocode>

    * draw the original image (with a solid color, say red);
    * create a new mutable image and change all the (say, red) pixels to transparent;

    for (an x and a y in the new image starting from a coordinate) {
    * change all the pixels to another color (say, black), starting with a low opacity and increase the opacity as x and y gets bigger;
    }

    * overlay the new image on the original image.

    </pseudocode>

    I take it that this is useful for creating a shadow effect? Sorry if I seem a bit slow on the uptake. I'm not a graphics programmer by training.

    Thanks!

  9. #9
    Regular Contributor
    Join Date
    Aug 2003
    Posts
    134
    Yeah, but you don't need to set the transparancy in the second iteration:

    * draw original original image (may be anything) on Graphics;

    * create an new empty Image (may be any colour);

    * On the new Image, set the pixels you like to the colour and opacity you like;

    * Overlay the new image;

    * Optimize the code (creating that image each and every time might suck).

    Ofcourse you can also do it the other way around. And yes, it is actually doing the same as having transparancy in your sprites. Those pixels are defined non opaque.

    But say you would like to blend your game character to blue when it is under water:

    * draw game field,
    * draw sprites,
    * overlay your sprites with a filled rectangle (two triangles for example):

    public void draw(Graphics g) {
    DirectGraphics dg = DirectUtils.getDirectGraphics(g);

    // draw game field
    dg.drawPixels(........);

    // x=sprite x
    // y=sprite y
    // h=sprite height
    // w=sprite width

    dg.fillTriangle(x,y,x+w,y,x+w,y+h,0x770000FF);
    dg.fillTriangle(x,y,x+w,y+h,x,y+h,0x770000FF);
    }

  10. #10
    Regular Contributor
    Join Date
    Aug 2003
    Posts
    134
    Erhm, I did make a mistake. You are right about making the new Image completely transparent first. However when you use the createImage() method DirectUtils provides you can set Alpha directly for the entire Image (that method takes argb colour as well).

    So for a complete transparent Image use:

    DirectUtils.createImage( width, height, 0x00000000 ); // It doesn't matter what colour you use, it is transparent anyway.
    Last edited by dannyc4; 2003-09-14 at 20:23.

  11. #11
    Registered User
    Join Date
    Mar 2003
    Posts
    8
    > danny c4:

    I think I'm starting to get the picture now. I tried overlaying progressively lighter triangles to create a light & shadow effect on my images. It looks okay, but still very rough.

    This is way better than my original plan to manipulate pixels directly, by gradually changing the colors of each pixel in x until it becomes completely black.

    Of course, it would be best to create really small triangles (or polygons) and tile them over the original image, but I guess the capabilities of current phones in the market may not be up to scratch for that.

  12. #12
    Regular Contributor
    Join Date
    Feb 2006
    Posts
    55

    Re: Dynamically change the color of a PNG?

    Hi ALL!
    I came across this very interesting thread searching for a way to draw an image overlay in a video for example draw a halbtransparent rectangle over it. Do you have any idea whether I could do that? And HOW?
    PLEASE HELP!
    Nina

  13. #13
    Registered User
    Join Date
    Mar 2003
    Location
    Russia, Saint-Petersburg
    Posts
    40

    Smile Re: Dynamically change the color of a PNG?

    May be it would be interestingly for members of the topic.. I have placed on my web page (http://www.igormaznitsa.com) J2ME class for dinamic creation of PNG files, working with palette and graphical primitives..

  14. #14
    Super Contributor
    Join Date
    Mar 2003
    Location
    Israel
    Posts
    2,280

    Thumbs up Re: Dynamically change the color of a PNG?

    Well, the topic is a bit old (it was started three years ago), but that's a great resource so thanks.

    shmoove

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
×