Scale and colour a bitmap image at the same time

Hello,

I've been playing around with the drawBitmap2 and drawScaledBitmap functions to achieve the goal of using only one bitmap to scale across devices of different sizes (which drawScaledBitmap does) and colour the bitmap (which drawBitmap2 does).

But is there a trick to get them both done at the same time?  Please advise if at all possible.

  • Where does the bitmap come from? Isn't it a drawable resource compiled in the app? If it is then why bother scaling it at runtime when it can be done at compilation time?

  • But is there a trick to get them both done at the same time?  Please advise if at all possible.

    One approach you can try is to create a BufferedBitmap with the target dimensions. Then, use drawScaledBitmap to draw onto the Dc of the BufferedBitmap, and finally use drawBitmap2 to render the BufferedBitmap to the screen.

  • It's a PNG file that I would like sized and coloured depending on the type of device.

  • Thanks for your helpful response. I understand the creation of the buffered bitmap, but the documentation does not demonstrate how to draw into the buffered bitmap, at least not that I am aware of.  Do you know how to do that?

  • It's a PNG file that I would like sized and coloured depending on the type of device.

    One option—if it suits your use case—is to define the image as a resource and use scaleX and/or scaleY as a percentage of the screen width. This allows for flexible scaling across devices.

    Thanks for your helpful response. I understand the creation of the buffered bitmap, but the documentation does not demonstrate how to draw into the buffered bitmap, at least not that I am aware of.  Do you know how to do that?

    You can draw into a BufferedBitmap by calling getDc() on it. That returns a Dc object, which you can then draw to using methods like drawScaledBitmap().

  • What did you end up doing to achieve this?

  • I created two versions of the image I needed - one large and one small.  In my code I determined which one had a vector font, and applied the result to all the devices.  I used the larger one for those with vector font with scaled bitmap, as well as the larger devices without vector using normal bitmap, and the smaller ones for the rest.  It helped that my image was only about a third to half of the screen, otherwise I would have needed more size variations.  I did not use the coulour bitmap in the end.  I hope this code helps.

    var hasVectorFont;
            if (Toybox.Graphics has :getVectorFont) {hasVectorFont = true;} else {hasVectorFont = false;}
            System.println("has vector font: "+hasVectorFont);  

            // greeting icons
            if (hasVectorFont == false) {
                if(screenWidth >= 390 || deviceGroup.equals("venusq2") ) {
                    dc.drawBitmap(screenWidth*0.15, screenHeight*0.4, WatchUi.loadResource(greetingImage));
                } else {
                    dc.drawBitmap((screenWidth <= 218 ? screenWidth*0.15 : (screenWidth <= 240 ? screenWidth*0.15 : screenWidth*0.16)),
                    screenHeight*0.4, WatchUi.loadResource(greetingImageSmall));// use smaller version
                }
            } else {
                dc.drawScaledBitmap(screenWidth*0.15, screenHeight*0.4, screenWidth*0.7, screenHeight*0.4, WatchUi.loadResource(greetingImage));
            }