9 Replies Latest reply on Dec 18, 2009 10:53 AM by ngarg

    How to render 3000 by 4000 pixel PNG quickly?

    ngarg Level 1

      Hi,

       

      I am trying to display a bunch of PNG files in a scroll view. Each PNG is approximately 3000 X 4000. To limit the memory usage, I am loading and unloading images as they come and go out of view. This works but there is a slight delay when the PNG file is rendered.

       

      Is there a way to render PNG file quickly?

        • 1. Re: How to render 3000 by 4000 pixel PNG quickly?
          Flex harUI Adobe Employee

          If you load a PNG it always takes an extra frame before it appears.   You could build a cache of bitmapData's from the PNGs that will reduce flicker in certain conditions.

           

          Alex Harui

          Flex SDK Developer

          Adobe Systems Inc.

          Blog: http://blogs.adobe.com/aharui

          • 2. Re: How to render 3000 by 4000 pixel PNG quickly?
            ngarg Level 1

            Thanks Alex,

             

            I think I should elaborate my scheme a little bit more. They way I have implemented is as follows:

             

            I cache all the binary data for the PNG images (approx 300-400K) into memory.

            Everytime i require to render an image. I use the Loader.loadBytes method and then use the BitmapData object to fill, using Graphics.beginBitmapFill method, to draw the image on to the Group component.

             

            The reason I am not caching the actual bitmapData object is because caching 10 images can take upto 500-600 MB of RAM. (3000 X4000 X 4 byte (32 bit) ~ 50MB per image + other overheads). I may have to load more than 10 images in the application.

             

            So the solution I came up with is to set the Group components width/height to that of the desired image viewing size. This Group component acts as a image placeholder. Whenever, a certain image holder comes into the viewport, I fire up a load image event, which call the Loader.loadBytes and then fills up the Group component. This way my memory consumption is limited.

             

            Downside to this approach is that there is a slight delay (1-2), when the Group component graphics area is filled up with the image. Also, sometimes, the scroller freezes, when graphic area is being filled up with the image.

             

            Is there a way to eliminate this delay?

             

            Thanks.

            • 3. Re: How to render 3000 by 4000 pixel PNG quickly?
              Flex harUI Adobe Employee

              You might try saving the BitmapData to a compressed ByteArray.  It won't be as efficient as PNG, but will save you something.  If you can simply addChild a Bitmap instead of using Loader you should get instantanteous results (unless there's just too many bits to process).

               

              Note that unless you're using that resolution, you'll save bandwidth and performance by downscaling the PNG on the server before sending them to the client.  Scene7 is a service that can help you with that.

               

              Alex Harui

              Flex SDK Developer

              Adobe Systems Inc.

              Blog: http://blogs.adobe.com/aharui

              1 person found this helpful
              • 4. Re: How to render 3000 by 4000 pixel PNG quickly?
                ngarg Level 1

                Hi,

                 

                How do I create a BitmapData object from a ByteArray? The only way I could figure out was using a Loader.loadBytes method.

                 

                Also, do you know a direct way to add a Bitmap as a child of the Group component. Flash Builder gives an error that Bitmap should be added using addElement or set as a skin.

                • 5. Re: How to render 3000 by 4000 pixel PNG quickly?
                  Flex harUI Adobe Employee

                  BitmapData.setPixels/getPixels

                   

                  Alex Harui

                  Flex SDK Developer

                  Adobe Systems Inc.

                  Blog: http://blogs.adobe.com/aharui

                  • 6. Re: How to render 3000 by 4000 pixel PNG quickly?
                    David_F57 Level 5

                    Rather than using a group container why not just use an image component so then the bytearray is the source myimage.source=mybyteArray once the the image leaves the viewport set the source to null.

                     

                    David

                    • 7. Re: How to render 3000 by 4000 pixel PNG quickly?
                      ngarg Level 1

                      Will I get any performance boost, if I use the Image control?

                      • 8. Re: How to render 3000 by 4000 pixel PNG quickly?
                        David_F57 Level 5

                        The image control does all the work for you when playing with bytearrays, if you have a byte array in memory then using image.source will avoid the screen flicker. Image handles the conversion of bytearray to display data for you and there is nothing in the image component code that suggests its a bad choice.

                         

                        David

                        • 9. Re: How to render 3000 by 4000 pixel PNG quickly?
                          ngarg Level 1

                          They way I solved this problem, was to generating lower resolution image (1400 X 1900) . That way, the loading time improved significantly. Here are the steps I did to implement it:

                           

                          a) Load the binary and cache it. (You can use URLLoader and URLRequest objects to do that)

                          b) Whenever, the image comes inside the scroll view (Use the VerticalLayout's fractionInViewElement method), I paint the image on to a Group using

                           

                          graphics.beginBitmapFill(bitmapDataObject)

                          graphics.drawRect(0,0,width, height);

                          graphics.endFill

                           

                          c) In the background I maintain a BitmapData object, which I dispose of as soon as the image moves out of the viewing area.

                          d) It works perfectly. At any point in time, my memory consumption doesn't exceed (200MB).In the release version, I am hoping it is going to be far less.

                           

                          Thanks for your help.

                           

                          Update 12/18/2009:

                           

                          Checkout my latest entry under " TileLayout spark Item Renderer and Zoom in and zoom out". I have also included a working example. Make sure that you add  a list of images under bin-debug/data directory with prefix image_0000, ..., image_nnnn.