Image size increased a lot with MakeImageRequest

Hi,

I am downloading the attached png from a website with MakeImageRequest This image size on disk is approx 4k. What I noticed is that after reception of this image in my application (running on the Edge 1030), it uses approx 140k memory for this image. I played around with the pallets, bpp, etc, but this does not help. The only thing that really helps, is to decrease the size of the image.

Who can help me with the following:

1) is this behavior correct?

2) What can I do to decrease the memory size of the image in my application?

Thanks!

  • The edge1030 uses 16-bit color, so the memory required for an uncompressed copy of this full color image is 261x268 pixels @ 2 bytes/pixel = 139896 bytes = ~137 KB. 

    You should be able to reduce the in-memory size by providing a :palette option to makeImageRequest. I've verified that the image size is reduced when running on the simulator, but have not yet taken the time to verify it works on device. Given that the image handling is done in shared code, I'd be surprised if this didn't work.

    Travis

    using Toybox.Application;
    using Toybox.Graphics;
    using Toybox.System;
    using Toybox.WatchUi;
    
    class TestImageRequestDelegate extends WatchUi.BehaviorDelegate
    {
        hidden var _view;
    
        hidden const _palettes = [
            null,
            [ Graphics.COLOR_RED, Graphics.COLOR_ORANGE, Graphics.COLOR_YELLOW, Graphics.COLOR_BLUE, Graphics.COLOR_GREEN, Graphics.COLOR_WHITE ],
            [ Graphics.COLOR_RED, Graphics.COLOR_ORANGE, Graphics.COLOR_YELLOW, Graphics.COLOR_BLUE, Graphics.COLOR_WHITE ],
            [ Graphics.COLOR_RED, Graphics.COLOR_ORANGE, Graphics.COLOR_YELLOW, Graphics.COLOR_WHITE ],
            [ Graphics.COLOR_RED, Graphics.COLOR_ORANGE ],
            [ Graphics.COLOR_RED ],
        ];
    
        hidden var _palette;
    
        function initialize(view) {
            BehaviorDelegate.initialize();
            _view = view;
            _palette = 0;
        }
    
        function onSelect() {
            var url = "https://www.mariowiki.com/images/thumb/0/0d/Raccoon_Mario_Artwork_-_Super_Mario_Bros._3.png/200px-Raccoon_Mario_Artwork_-_Super_Mario_Bros._3.png";
    
            var params = {
            };
    
            var options = {
                :palette => _palettes[_palette]
            };
    
            _palette = (_palette + 1) % _palettes.size();
    
            Communications.makeImageRequest(url, params, options, self.method(:onImageResponse));
        }
    
        function onImageResponse(code, bitmapResource) {
            if (code == 200) {
                _view.setImage(bitmapResource);
            }
        }
    }
    
    class TestImageRequestView extends WatchUi.View
    {
        hidden var _bitmap;
    
        function initialize() {
            View.initialize();
            _bitmap = null;
        }
    
        function setImage(bitmapResource) {
            _bitmap = bitmapResource;
            WatchUi.requestUpdate();
        }
    
        function onUpdate(dc) {
            dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_BLACK);
            dc.clear();
    
            var cx = dc.getWidth() / 2;
            var cy = dc.getHeight() / 2;
    
            if (_bitmap != null) {
                cx -= _bitmap.getWidth() / 2;
                cy -= _bitmap.getHeight() / 2;
    
                dc.drawBitmap(cx, cy, _bitmap);
            }
            else {
                var messageString;
    
                var deviceSettings = System.getDeviceSettings();
                if (deviceSettings.isTouchScreen) {
                    messageString = "Tap Screen";
                }
                else {
                    messageString = "Press Select/Enter";
                }
    
                dc.drawText(cx, cy, Graphics.FONT_SMALL, messageString, Graphics.TEXT_JUSTIFY_VCENTER | Graphics.TEXT_JUSTIFY_CENTER);
            }
        }
    }
    
    class TestImageRequestApp extends Application.AppBase
    {
        function initialize() {
            AppBase.initialize();
        }
    
        function getInitialView() {
            var view = new TestImageRequestView();
            return [ view, new TestImageRequestDelegate(view) ];
        }
    }
    

  • When running that code in the simulator, the full color image brings the app memory usage up to 124.5kB, and the 6 color image cuts that down to 85.2kB.

  • Hi Travis,

    Thanks for the reply. I will adjust the code and test with it.

    I will let you know the results.

  • Travis, I know that method does indeed work on the devices.  I am using a reduced palette to control memory usage on watch devices for my Weather Radar Widget.  Early on I found out that full 64 colors on 240x240 devices such as the FR935 and F5 which have a widget memory limit of 65k would run out of memory, but the 16 color devices worked fine at full screen.  My initial method was to reduce the image side to less than full screen.  Later I found that reducing the palette on all watch devices allowed me to increase the image to full screen, but also helped to reduce image download time as well as limiting the memory usage.

  • - Thanks. I was pretty sure it worked on devices, I was just too lazy to test it without someone saying it was broken. Sweat smile