Dynamically changing the color of a monochrome bitmap

I have several monochrome bitmaps that I use.  I discovered that I can change the color in my drawables.xml file simply by specifying a different palette, as follows:

<drawables>
  <bitmap id="BlackArrowUp" filename="Black.Up.85x85.png" dithering="none">
    <palette>
      <color>000000</color>
    </palette>
  </bitmap>

  <bitmap id="WhiteArrowUp" filename="Black.Up.85x85.png" dithering="none">
    <palette>
      <color>FFFFFF</color>
    </palette>
  </bitmap>
</drawables>

That works great (in the simulator at least - haven't tried it on an actual device yet.)  But it got me thinking - can I do the same thing without having to define all the "white" images in the XML file?  That is, can I map the palette when I go to draw the image?

I tried creating a BufferedBitmap with a palette of [ COLOR_RED, COLOR_TRANSPARENT ].  But when I attempt to draw the "black" image, it crashes and I get the error:

Error: Unhandled Exception
Exception: Bitmap source color cannot be found in the target palette

Has anyone tried this, or something similar, and gotten it to work?  It's not that big of a deal for me to just create multiple resources in the drawables.xml file.  But it would be "cleaner" if I could just have one set of images, and change the color when I go to draw them.  Thanks!!

  • Have you considered creating a custom font with your monochrome bitmaps/icons?

  • That's how I do it.  A custom font, then use dc.setColor().  Using bitmaps means you have a separate one for each color.

  • Thanks for the suggestion - I have not tried using a custom font.

    After some experimenting, I was actually able to get it to work.  For some reason, setting a palette with only 2 colors (black, transparent) did not work.  Out of desperation, I created a BufferedBitmap with a 4-color palette (black, black, black, transparent).

    Then, I drew the monochome (black) bitmap into the BufferedBitmap.

    Then, I called setPalette on the BufferedBitmap with another 4-color palette (red, red, red, transparent).

    Then, I drew the BufferedBitmap into my primary Dc.  Sure enough, it showed up as red.

    I'm still not sure why I need a 4-color palette to get this to work.  (I verified in the debugger that my bitmap is 1 bpp - ie, 2 colors.)  But at least I have something that works now, and I can remove the other bitmaps from the drawables.xml file.  (And only have to maintain bitmaps in a single color.)

  • Don't forget that with CIQ 4 devices, BufferedBitmaps are different.  All in all a custom font will be easier.

  • Yeah, if I had to do it again, I'd probably go with a custom font.  But I have it working now on CIQ2->CIQ4 devices.

    For anyone else that decides to go down this path, I also had to handle the monochrome devices (Descent G1, Instinct 2 series) as a special case.  Fortunately, they only have the option of a white background, so I can just draw my black bitmap as-is.  I don't need to try to change its color.

    But a custom font would avoid the need for handling these special cases.

  • A CIQ app on the I2 can have a black background  So you still have B on W and W on B.

  • I should point out that this particular project is a data field, not an app or watchface.  In the simulator, I only have the option for a white background for data fields.

    But you're 100% right -- it would certainly be possible to ignore the data field background setting and have a data field with a black background and white foreground.  But for my purposes, I'm not worried about it.  I'm doubtful anyone with an Instinct watch is going to care about my data field anyway.  lol.  

    Thanks again for all the suggestions.  I appreciate you taking the time to reply even if I ended up going a different route.  Other people that read this thread will certainly benefit from your comments.  :-)

  • On a real I2, in things like the run activity, you can set either a black or white background.

    Run Settings>Background Color

    Also, the DF in the subscreen is the opposite color.

  • Thank you.  I thought it was strange that the background couldn't be changed, but there are certainly other weird things Garmin does with the watches.  I guess I'll chalk this up as a simulator bug.