1

I have a set of high resolution pictures. Each of these pictures shows a car on a different angle. The idea is to switch from one picture to the next so it gives the user the impression the car is turning.

Flex takes to much time to render the picture. Therefore the switch happens with a lagging effect instead of smooth like its suppose to.

First I add the images on a View calling initLeftRightModel onCreateChildren:

        protected function initLeftRightModel():void
        {
            if(containerLeftRight && definitionLeftRight)
            {
                for(var i:int = 0; i<36;i++)
                {
                    var img:Image = new Image();
                    img.height = 1068 * scaleFactor;
                    img.width = 2048 * scaleFactor;
                    img.contentLoader = ldr;
                    img.contentLoaderGrouping = 'gr1';
                    if(i < 10 ) img.source = modelPath+'/0'+i.toString()+'.png';
                    else img.source = modelPath+'/'+i.toString()+'.png';
                    containerLeftRight.addElement(img);
                    if(i>0)img.visible=false;
                }
        }

I call the function turnModelTo to switche the visibility of the last picture to false and the next to true:

        /**Turns the model in the direction of the finger according to the variation of X.**/
        protected function turnModelTo(newX:Number):void
        {           
            var val:int = 0;
            direction = (oldX != newX)?oldX - newX:direction;
            if(oldX > newX) val =  (oldValue+1<36)?oldValue+1:0;
            else if(oldX < newX) val = (oldValue-1>0)?oldValue-1:35;
            else if(oldX == newX) val = oldValue;
            oldX = newX;

            containerLeftRight.getElementAt(oldValue).visible = false;
            oldValue = val;
            containerLeftRight.getElementAt(val).visible =  true;
        }

The images are loaded only one time and I am using caching. The problem is with the rendering of images.

The resolution of the images is 2048x1068. This is a mobile project and I am currently testing on iPad Air. I appreciate any help or ideas about how to best code this functionality.

Thanks

Dave
  • 598
  • 2
  • 4
  • 17
  • 2
    Why don't you try to buffer the images instead of reading them when needed. Knowing that this is a mobile platform, Buffer only the image one before , the current , and the next image. Also I suspect , the image resize is the slowest operation amongst them all. – Tejas Kale Mar 07 '14 at 11:08
  • @TejasKale Could you answer the question and tell me how you would do that? I though all images were cached. Also the resize of the image is done only one time and that is not when on switch. Or is it? – Dave Mar 07 '14 at 12:07
  • I highlighted the above only as a possible algorithm, I have no idea on how to implement it since i have never worked in actionscript or flash. – Tejas Kale Mar 14 '14 at 08:45

2 Answers2

1

Using so many and so large pictures on mobile, with Flex... it's not surprising you have performance problems.

First thing, you should adapt the images size to the device, on server side, if it's possible. Loading 36 HD images with a 3G connection will take a rather long time. And if it's to reduce their size on the device, it's a loss of time.

Then ensure you use a spark.components.Image and not the old Image class.

Last but not least, use a cache. It's not clear in the code in your question if you defined one, because the way the variable ldr is initialised is not shown. It should be something like:

var ldr = new ContentCache();
ldr.enableCaching = true;
ldr.enableQueueing = true; 

Alternatively, if the images aren't supposed to change, you can embedd them in the application, instead of loading them, and use BitmapImage components to display them. The app will be heavier, but you won't have any loading time.

Pascal Le Merrer
  • 5,883
  • 20
  • 35
  • The pictures are added initially and I am using ContentCache. My problem is with Rendering of the successive pictures. I would like to know a way to make the rendering of the next picture faster. Or I want to know if there is a better way than the one I am using which is: adding all pictures in the beginning and switch from picture A to B by changing there visibility. – Dave Mar 12 '14 at 08:09
1

This is a clear case where doing the computations on the GPU would make things a lot better. You should first of all switch renderMode to GPU. Go to application.xml, and edit the following:

<initialWindow>
<renderMode>gpu</renderMode>
</initialWindow>

You should also use the Bitmap class instead of the Image class. This will upload your png files as textures to the GPU. Here is how you do it How do you load a bitmap file into a BitmapData object?

Community
  • 1
  • 1
Mihai Raulea
  • 428
  • 1
  • 3
  • 18
  • Thanks fot the answer Mihai. Unfortunately I can't switch to GPU mode as I am using effects. To be more specific I am using a DisplacementMapFilter to create a magnifying glass effect on top of the image. Effects only work on CPU mode. If you know another way of making a magnifying glass I would be glad to get rid of this effect. – Dave Mar 19 '14 at 11:13
  • Hi Dave, you may use the starling framework, and use their implementation. Here is a link: http://doc.starling-framework.org/core/starling/filters/DisplacementMapFilter.html. This way, you won't be forced to use the CPU. – Mihai Raulea Mar 20 '14 at 15:55
  • I noticed that the starling filter uses Texture to calculate displacement while the flash filter uses a BitmapData object containing the displacement map data. How to I cope with that. I am using two circles on top of each other as displacement map data. – Dave Mar 20 '14 at 16:38
  • You can use Texture.fromBitmapData to generate the Texture object from your BitmapData. This will upload the BitmapData to the GPU. – Mihai Raulea Mar 20 '14 at 18:31
  • I have to give a look to starling right now I get this MissingContextError() from the empty() function I don't know how to initialize the context yet and the Starling.context is null. – Dave Mar 21 '14 at 07:53
  • 1
    I think you would be better off simply instantiating the Starling framework, instead of hand-picking classes, but this is just my opinion. It won't bring your package size up by too much, and it will help you in other projects as well. – Mihai Raulea Mar 22 '14 at 13:51
  • Let me know how it goes, and if i can help you further. Good luck! – Mihai Raulea Mar 25 '14 at 09:18