Putting graphics off the IDE

I have a major refactoring job to do, and I think I might know how to do it, but I thought it would be a good idea to get different opinions and suggestions.

I’m using REALStudio2011r3 but that doesn’t matter, and I’m writing xplat. I develop on the Mac and compile both Win and Mac on Mac.

It’s easy but vast. Basically I am taking a large project and changing how I deal with graphical resources. From Day One I dropped in my graphics into the IDE, and making it more complicated I split them into TWO: the graphic and the mask, the pair being XXX.png and the mask always being XXX_mask.png. I only use PNG. Then I take the XXX object and set the Transparent property to White (1), and the Mask property to the XXX_mask file.

I did all this for older version reasons, when Alpha channels of PNG’s wasn’t supported, et. al.

Now, my programs take too long to start up, probably because they are loading up all these graphics and setting them up. Not only that, it’s very ineffecient because most of the graphics are not seen immediately. Most of the are menu-item things and icons for hundreds of different objects.

I’d like to switch to deleting all these graphical objects and changing to a “load-as-needed” basis, where the graphics are files outside the app and loaded and persistant when necessary.

Another benefit of this would be that REAL Win dithers larger graphics pretty badly. For example, all my graphics are done 128x128, and frequently they are dithered to 16x16 in my app. OSX is very nice with it but Win is uglier than crap. Using the off-world system, I can make different versions much easier without loading down the app with too many objects on-world.

I’ve heard plenty of people have already abandoned putting graphics as objects in the IDE. How do you do it? Could I ask, how would you approach this refactoring? What functions would you write and how would you implement this? (I’m not asking anyone to code it but I’m asking for a basic idea-map, but with more specifics.)

Thanks!

keeping the graphics is the resource area doesn’t keep you from creating a “load on demand” scenario. As a matter of fact it will make it easier to package/deploy. Simply do not do all you image processing on app startup… do it once for each image, “on demand”. It will still take the same amount of time, but that time will be spread out over the users session, and won’t include processing images that they don’t reference.

Same as Dave, store all my graphics in a “Resources” folder which gets copied into the bundle on build or run.

I then load them as needed.

If you convert your images back to transparent PNGs or TIFFs, you can also compress them to help thin your application, I wrote ICNSmini just for this.

Isn’t that what he just said? Anyway, one option would be to create factory methods for each image, so you don’t have to change a lot of code. Each method would check if you have already loaded the image, and load it if necessary. If you’re clever with your naming conventions, you can also request different sizes. The factory method would return the image, of course, so the rest of your code continues to work as if it were still using the embedded image.

Old:

Property XXX as Picture    // dragged into the IDE
me.Icon = XXX

New:

Property mXXX as Picture    // a regular global property
Function XXX() as Picture
   if mXXX Is Nil then
      dim f as FolderItem = GetFolderItem("images/XXX.png")
      mXXX = Picture.Open(f)
   end
   Return mXXX
End Function
me.Icon = XXX

Of course, you could have a single helper method that takes the image name as string and an optional size and finds the right file on disk and opens it.

Function XXX() as Picture
    if mXXX Is Nil then mXXX = LoadImage("XXX")
    Return mXXX
End Function

You could also write an app that scans a folder of images and spits out a fully formed Xojo Module, but that might be overkill.

@Garth: how could you verify that your long startup-time is really due to the large number of graphics that your app uses? How many MBs are we talking here? How many pics? How about trying to combine pictures and masks first?

An idea for testing: replace a number of your graphics by very small dummy graphics, say 10x10 black. Then your app should start noticably faster.

Do you compress your graphics with http://pngmini.com/ or similar? This usually makes the images 80 to 90% smaller.

Tim and Beatrix were on track with my question, and both went in the same direction as I was thinking. (To the others, I have my graphics IN THE IDE, not just files in a “resources” folder. I thisnk this is a bad idea because the compiled app is forced to do a lot of work, loading all the graphics into process space initially, because the app want them when asked.)

Taking Tim’s idea, I’d make a single module out of it and do all my stuff there. I’d hardly have to touch my other code, the token XXX would represent a Method, not a object. Thanks.

Beatrix, you’re right as well to optimize the graphics too, but remember that no matter what I’ve got to take the stuff load-on-demand because of the Windows dithering awfulness. It’s not just the startup time, although I’m almost positive the startup time will speed up.

Does that PNG-MINI program decrease the quality of the PNG - is it lossy?

Also, I’ll add a question, since I have all these split PNG/Mask, whats a good program to combine them again? Please avoid any large graphic program aka Photoshop. I split them using a REAL-made splitter, that PNG Mask Extractor made by our own Brad Rhine.

Your own Xojo code :slight_smile:

It shouldn’t be too hard to loop over your files and match up XXX.png with XXX_mask.png. Then for each pair open them as Pictures and merge the mask using Picture.ApplyMask. Finally save that as PNG using Picture.Save(newFile, Picture.SaveAsPNG).

This is true only for Win, on a OS X app you have your images in a folder within the app bundle.
So for OS X using IDE images or “resource images” is the same. Maybe the difference will be only for win.
If you use PNG and Mask then you are building the real images in your app, if you use a true PNG then you can use the image immediately. Probably just joining the images and their mask will speed up your app loading time.

[quote=228236:@Antonio Rinaldi]This is true only for Win, on a OS X app you have your images in a folder within the app bundle.
So for OS X using IDE images or “resource images” is the same. Maybe the difference will be only for win.
If you use PNG and Mask then you are building the real images in your app, if you use a true PNG then you can use the image immediately. Probably just joining the images and their mask will speed up your app loading time.[/quote]

Windows now uses exactly the same scheme as Mac. Anything dragged into the project is stored in a Resource folder next to the executable. The Windows installation folder can be considered a form of bundle.

Unless I am mistaken, though, dragging the pictures into the project means they are all loaded upon launch. Hence the slow startup. It would probably be a lot faster to copyfile them into Resources and load them when needed. This probably means a slightly slower display, especially with hard drives. On average, though, and unless the pictures are real big, it is usually extremely fast.

The smaller the better. On the web where speed is all the more important, I use the “save for web” option in Photoshop, which produces drastically smaller pictures. But miniPng is about just the same. I have no idea what gif versus png means in terms of internal treatment for Xojo. I vaguely recall I think Norman mentioning Xojo actually keeps png as is. Don’t know about gif.

The miniPng compression is lossy. But for icons there is noticeable difference to the original.

All excellent suggestions, thank you.

I don’t think ApplyMask is in REALStudio, but I do have Xojo and I I can write a little temporary program.

Thanks Michel for the confirmation. As it is now, what I’m doing is very inefficient as the usual session a person sees perhaps 5% of the graphics. And again, handling it as-needed gives me an excellent opportunity to pass a correct sized graphic that looks good, since REAL/Xojo Windows dithers so poorly I don’t care whose to blame).

Gotta be PNG. No color issues or compression. These graphics may be called on to be big 128x128, even bigger as well as small 16x16. 16 pixels is more common. Still, the as-needed thing makes this moot.

Antonio, you may be right that combining the images again may be the crux of everything anyway.