ImageList items as Reference?

DaveW

Active Member
Licensed User
Longtime User
I am creating a set of images and storing them in an imagelist. Everything worked OK until I tried to resize each image (using DrawerEx) before adding it to the imagelist. If I do that the images are created and resized correctly but if I look at the contents of the imagelist all the images are the same - they are all the last image to be added. I have done checks such as saving each image as as bmp as it is created, before and after resizing and the last imagelist item added. All is correct. But if I write out ALL the images in the imagelist each time I add one, then I see that in each iteration, all the images are the same as the last one added. It seems that the imagelist image is created as a reference to the 'current' source image, not the source image itself!

The strange thing is this only happens if I add a resize step. Just creating and adding the source image works fine, all the imagelist images remain unique individuals!

the code I am using is

rectdest & rectsrc object RectangleEx
sourcebmp.New2(w,h) 'object bitmap
outputbmp.New2(w,h) 'object bitmap
Createdimg.New1 'object ImageClass
resizebmp.New2(outputbmp.Value) 'object DrawerEx

(loop)
(make the image in Createdimg.image)
sourcebmp.Value = CreatedImg.Image
resizebmp.DrawImage(sourcebmp.Value,rectsrc.Value,rectdest.Value,False)
imagelist1.Add(outputbmp.Value)
(end loop)

This does work:
(loop)
(make the image in Createdimg.image)
sourcebmp.Value = CreatedImg.Image
imagelist1.Add(sourcebmp.Value)
(end loop)

I'm afraid posting the whole program is not really feasible, it generates the images from files I can't distribute. Cutting out the problem bit will also be complex.
 

DaveW

Active Member
Licensed User
Longtime User
OK, I can understand if you are sceptical! So I have put together a demo.

It's a stripped down version of my program so some object names might be a bit obtuse but it does the job. Run it and press the "Good" and "Bad" buttons. The buttons run the same loop with a small difference at the end. Each iteration of the loop generates a BMP in a different shade of grey and adds it to the imagelist. At the end of each loop, all the images currently in the imagelist are written out as BMP files.

This generates two sets of 21 BMPs. The good ones are done without resize, the bad with resize. You will see that in the good one, "0" is always white, "1" a shade darker, etc. In the bad set, "0" is white in the first pass, darker in the second, etc. This shows that when resize is used the imagelist gets rewritten when an item is added (or the images are references to the last image).

If anyone can explain the logic behind this I would love to hear it! A solution would be even better :)
 

Attachments

  • ImageList.sbp
    1.9 KB · Views: 193

Erel

B4X founder
Staff member
Licensed User
Longtime User
You are correct ImageList only stores a reference to the actual image.
Otherwise each image would have been duplicated taking more memory resources.

B4X:
If goodorbad= "good" Then
            sourcebmp.Value = GridImg.Image
            imagelist1.Add(sourcebmp.Value)
        Else
            sourcebmp.Value = GridImg.Image
            gridbmp.New2(40,40) ' <---------
            resizebmp.DrawImage(sourcebmp.Value,rectsrc.Value,rectdest.Value,False)
            imagelist1.Add(gridbmp.Value)
        End If
While you are recreating GridImg every iteration you also need to recreate gridbmp if you want to use it multiple times.
 

DaveW

Active Member
Licensed User
Longtime User
Thanks Erel,

I can see it's going to take some time to get my head round this stuff! Sometimes it's so easy and other times it just makes my brain hurt!

By the way, the correction should be:

sourcebmp.Value = GridImg.Image
gridbmp.New2(40,40) ' <---------
resizebmp.New2(gridbmp.Value) '<----------
resizebmp.DrawImage(sourcebmp.Value,rectsrc.Value,rectdest.Value,False)
 
Top