Bitmap Palette cannot be larger than the target palette

Hello, I am drawing Bitmap to BufferedBitmap. Both have set defined palette with same 16 colors. This always results in exception: "Bitmap Palette cannot be larger than the target palette". If I remove one color from palette of bitmap, everything works well. 

Everything is defined in code, not via resources xml. Is there some bug or bitmap loaded via makeImageRequest always automatically get also transparent color as addition to defined palette? There is no way for me to check that as getPalette works only for Buffered Bitmap and not Bitmap. 

How can I fill BufferedBitmap with bitmap using all its colors? Thanks

  • Using resources - transparent is disabled like this, maybe you need something similar.

    <palette disableTransparency="true">

  • I am aware of this. According to documentation: 

    Note that Bitmaps with a palette that are generated by the resource compiler will have an additional transparent index at the end of the specified palette unless the disableTransparency flag has been specified.

    So because I loaded it via makeImageRequest in code, there shouldn't by any added transparent color. But I don't know how to verify this. 

  • A quick test using makeImageRequest shows that I'm able to reproduce the issue you describe:

    using Toybox.WatchUi;
    using Toybox.Graphics;
    
    class TestDelegate extends WatchUi.BehaviorDelegate {
    
    	hidden var _palette = [
    		Graphics.COLOR_ORANGE,
            Graphics.COLOR_DK_BLUE,
            Graphics.COLOR_BLUE,
            Graphics.COLOR_BLACK
        ];
                                  
        function initialize() {
            BehaviorDelegate.initialize();
        }
    
        function onSelect() {
            var url = "https://dummyimage.com/100/ff0000/ffffff.png";
    
            var params = {
            };
    
            var options = {
                :palette => _palette,
                :maxWidth => 100,
                :maxHeight => 100,
                :dithering => Communications.IMAGE_DITHERING_NONE
            };
    
            Communications.makeImageRequest(url, params, options, method(:responseCallback));
        }
    
        function responseCallback(responseCode, bitmapResource) {
            responseCode = responseCode;
            if (responseCode == 200) {
            	try {
            		//var new_palette = [];
            		//new_palette.addAll(_palette);
            		//new_palette.add(0x000000);
            		
    	            var buf = new Graphics.BufferedBitmap({
    				    :width => 100,
    				    :height => 100,
    				    :palette => _palette,
    	            });
    	        
    	        	var buf_dc = buf.getDc();
    	        
    	        	buf_dc.drawBitmap(0, 0, bitmapResource);
    	        }
    	        catch (e) {
    	        	e.printStackTrace();
    	        }
            }
        }
    }

    If I tweak that test to add another entry to the palette used by the BufferedBitmap, I do not run into the exception. Another test helps to demonstrate that if the palettes are indeed the same that no error is reported..


        var buf1 = new Graphics.BufferedBitmap({
            :width => 10,
            :height => 10,
            :palette => [
                Graphics.COLOR_DK_GRAY,
                Graphics.COLOR_LT_GRAY,
                Graphics.COLOR_BLACK,
                Graphics.COLOR_WHITE
            ]
        });
       
        var buf1 = new Graphics.BufferedBitmap({
            :width => 10,
            :height => 10,
            :palette => [
                Graphics.COLOR_DK_GRAY,
                Graphics.COLOR_LT_GRAY,
                Graphics.COLOR_BLACK,
                Graphics.COLOR_WHITE
            ]
        });
            
        var buf1_dc = buf1.getDc();
            
        buf1_dc.drawBitmap(0, 0, buf2);

    So, it looks to me like the BitmapResource that is passed off to the simulator with makeImageRequest uses an additional palette entry that you are not expecting. Since the user has no way to specify transparent (you only get 0xRRGGBB to describe the pixel color), it seems that the code that does the palettization has to assume transparency is used and add it to the palette.

    It seems that we should add support for a `:disableTransparency => true` option to be passed to makeImageRequest, and maybe one to the options for BufferedBitmap.

    Note that this testing was done with the simulator only. It is possible that the system that handles the image from a device does not have this problem.

  • I must appreciate your almost scientific approach, thanks for your support Travis! :-) 

    I agree with your result. I did test it even with real device and it behaved same as in simulator - so it is global issue.

    So I hope it will be possible to fix it in some next CIQ release - before that I will be shorter by one color (which will be noticeable in my planned service).

  • Former Member
    Former Member over 5 years ago in reply to Travis.ConnectIQ

    It should be possible to specify Graphics.COLOR_TRANSPARENT when specifying the palette for a BufferedBitmap.

  • Hi Brian, I don't understand - do you mean override transparency color by other? Can you provide some more details how to achieve that? Thanks

  • He is saying that if you want to put transparent pixels into a BufferedBitmap, you should be able to specify that when you initialize:

    var buf1 = new Graphics.BufferedBitmap({
            :width => 10,
            :height => 10,
            :palette => [
                Graphics.COLOR_DK_GRAY,
                Graphics.COLOR_LT_GRAY,
                Graphics.COLOR_BLACK,
                Graphics.COLOR_WHITE,
                Graphics.COLOR_TRANSPARENT, // there are transparent pixels
            ]
        });

    I'm not exactly sure how this should work, but in my mind if you don't specify TRANSPARENT in the palette passed to makeImageRequest, the incoming image should have no transparent pixels. This would probably break a lot of apps, so it isn't likely to change, but that seems to be where the issue is.

  • Former Member
    Former Member over 5 years ago in reply to Travis.ConnectIQ

    Your previous suggestion of a `:disableTransparency => true` option for image request seems like the best option since it wouldn't break existing apps, and matches the resource compiler behavior.