6 Replies Latest reply on Mar 13, 2007 12:39 AM by Shiv_Kumar

    Sharing Image data across multiple Image Controls

      My issue is that I'm downloading dynamic images in a Flex application but these images need to show multiple places within the application. I find that Flex download these images for each instance of an Image control.

      I'd like to download the image once (in the one session) but be able ot re-use the image across multiple <mx:image> controls.

      The stuff I've tried assigns the image from one control to another but the first control goes blank.
        • 1. Re: Sharing Image data across multiple Image Controls
          jpwrunyan Level 1
          Sorry, I should have read this post before I made the other one. It sounds exactly like something I did with ComboBox and its server-based dataProvider... I will repost (paste) here:

          *one note: you probably need to use a Loader of some sort to get the jpg image data from the remote URL. Those classes are in the flash framework instead of the Flex framework so I think you will get best result with a custom AS3 component than trying to use a Flex component.

          I have not tried sharing with bitmaps or bitmapData objects yet. I have done sharing with simple XML data, URLLoader data, and DisplayObjects. The concept should basically be the same, though. My only hesitation is that bitmaps are terra incognito for me.

          However, if I were to try it, I would make a static bitmap data variable for some custom AS class that is similar to the SWFLoader or Image class (or even extends from them). Anyway, I will assume I have a class that displays a bitmap. I may have more than one of these classes on the screen at a time. The class will extend from a regular UIComponent and contain a Bitmap instance. However, the class will have one globally accessable (static) BitmapData class instance. Use a class initialization technique similar to that used when making custom styles to call a method the first time any instance of this class in instantiated. In that method set up your BitmapData class instance. In the regular instance constructor (or createChildren method or wherever), set the Bitmap instance's bitmapData reference to the static class reference. That should do it. You can set filters independently and show the same image on screen multiple times (hopefully) without getting tons of redundant bitmap data instances the way (I suspect) you do if you try the same thing with Image or SWFLoader.

          Like I said, I do this with ComboBox dataProviders where the dataProvider is taken from an external XML but I have multiple instances of the same ComboBox/dataProvider in one application (although I have the added incentive because the XML is furthermore taken from the server and I don't want to call the server EVERY time a combobox appears--but that's neither here nor there). Anyway, though, like I said, the same priniciple should apply here as well.

          And if you want to dynamically apply the same technique for any number of bitmap data (such that any one bitmap data is only loaded once and then never again), it shouldn't be too big a leap to set up a Dictionary (or just a regular array if you like) and then load the images from there to the appropriate instances based on some key value.

          I'm sorry I don't have any code worked out. But if you 're interested (and what I described above makes sense), then give it a whirl. If you have problems, post them.
          • 2. Re: Sharing Image data across multiple Image Controls
            Matlus Level 1

            Thank you for your extensive reply.

            I do the XML stuff like you do and don't have issues with that. I used that technique (without testing unfortunately) for bitmaps. It all works (or so it seems) on the surface, but I found that when I assign my cached bitmap to an image component I can't assign the same cached bitmap to another image component. I used the Loader (flash.display.Loader) class to get the bitmapsfrom the server.

            Loader has a LoaderInfo property which in turn has a content property (of type Bitmap) that can be assigned to an image's source property. However, the following will show the image only in Image2 (where Image1 and Image 2 are Image controls):

            Image1.source = loaderInfo.content;
            Image2.source = loaderInfo.content;

            While I'm writing this I think I should try creating a new instance of a Bitmap whose contructor expects a BitmapData instance which I can get from the loader.content.bitmapData.

            I'll let you know how that goes.

            • 3. Re: Sharing Image data across multiple Image Controls
              Matlus Level 1

              It works! So essentially, you need to create a new instance of a Bitmap pass it BitmapData from a previously loaded image/Bitmap. A simple approach that works could be:

              Image2.source = new Bitmap(Bitmap(Image(event.target).content).bitmapData);

              Where Image1 and Image2 are instances mx.controls.Image and an image has been previously loaded into Image1 using it's source property.

              Using the loader gives the same result. Disposing the bitmapData "clears" all images that used that instance of bitmapData as expected since they all point to the same memory location. I did this to confirm that the memory is being shared across all the images that were assigned the bitmapData in question.

              Thank you for your time and input.


              • 4. Re: Sharing Image data across multiple Image Controls
                Matlus Level 1
                Oops, I forgot the mention that the previous line of code was implemented in the complete event of Image1 and so "event.target" is a reference to Image1. So another way to write this code directly (for those interested) is:

                Image2.source = new Bitmap(Bitmap(Image1.content).bitmapData);

                Just make sure that Image1 is already loaded with an image!
                • 5. Re: Sharing Image data across multiple Image Controls
                  jpwrunyan Level 1

                  Thanks for the info. It was interesting. So basically, you can't share a static ref to a Bitmap among multiple Image components, but you can share a static ref to a BitMapData among multiple Bitmaps, right?
                  • 6. Re: Sharing Image data across multiple Image Controls
                    Shiv_Kumar Level 1
                    Yes, that is correct to a large extent. the "bitmapData" can be shared but you do need to assign a new instance of a Bitmap that is constructed using the bitmap Data. To explain this in terms of code.

                    Let's assume Image1 is an <mx:Image> control and an image has completed loading. Image 2 is another <mx:Image> control.

                    Image2.source = new Bitmap(Bitmap(Image1.content).bitmapData);

                    will work, however

                    Image2.source = Bitmap(Image1.content).bitmapData;

                    will not work as expected. In this case the bitmapData seems to get transferred to Image2 such that Image 2 shows the image while Image2 goes blank.

                    Sadly, after having got this far, I'm still stuck (on a completely different issue). You see when you assign the source of an image from an instance of a Bitmap (rather than a url or file name) the image does not seem to get "reset" (for lack of a better word).

                    So as an example, lets say Image 1 is the control in which I intend to display all my cached images at their original size (on demand by the user) and that the images are all cached and all I need to do now is let the user pick from a thumbnail of cached images to show the selected image in Image1 (at full size)

                    Lets say further that the first image the user selects is 320x240 and the second one she selectes is 640x480. To keep things simple here I've chosen sizes where the images are the same width to height ratio.

                    So when the user clicks on the first thumbnail we show her the full size image whose size is not set in code on the MXML file so it will display at full size (320x240). Next she selectes the second thumbnail. This is where the problem begins. This second image now shows at 320x240 because internally the Image1 control has got it's deminsions set when the first cached image was assigned to it.

                    So essentially I'm stuck here because I can't seem to find a way to "reset" Image1 and prepare it for the next selected image. There are a lot of hacks that could circumvent this issue, but I'd rather not go down that route.

                    The problem is further magnified if the images are not in the same ratio. Oh well, I have to move on to other stupid Flex quirks and will probably have to re-visit this in some time. You know how that goes.