Optimising Loading Large Images to Canvas

Hi Peter,

just came across this thread searching for something else. Your horse may be out of the barn on this already but I had a similar requirement for large scientific images. My solution was (because no common commercial app could handle an image > 32K x 32K) to divide the image into 2K x 2K tiles, and display only those that should be visible in the canvas at the current zoom & scroll. This way the picture is never bigger than the canvas/screen, and by storing the image data in shared memory using MBS shared memory plugins, I am only limited by RAM (or patience if you want to wait for VM swaps). It works fine with a 60K x 60K image (10 GB) on a 32 GB machine and would likely handle even larger ones but we never generated anything bigger (yet).
The tiles themselves are each stored using the JPEG2000 codec (running on as many cores as you have during file I/O) which gives ?6:1 compression with no discernible quality loss (better than JPEG). The relief was absence of noticeable “stitch lines” between tiles.
This took some doing but was the only way to make a fast viewer for large images, and it all works quite nicely and is very responsive for the user if you have enough RAM.

P.

I ran into a similar type of problem in our app a few years ago. As soon as I used DrawPicture, memory usage would jump considerably and there was no way to release all of the memory allocated. The problem was more noticeable with larger pictures but I discovered that all calls eventually leaked. The response I received was that it was due to the way RB interacted with CoreGraphics which wasn’t really much help.
After much sweat and tears I solved it via the following:

  1. Setting UseOldRenderer to true on the source and destination Graphics object (useful when drawing in a Paint event).
  2. Commissioning Christian @ MBS to write a custom pixel copying function which we use when we want to copy a rectangle from one picture to another picture.

This problem was discovered in RB2007 so it is disappointing to hear that it still exists today.

I do think the entire graphics system in Xojo is a bit fsck’d. It’s underlining design doesn’t seem to have changed from the Mac Quickdraw days and desperately needs bringing up to date. Apart from there being some very obvious omissions (for example: Bzier curves, paths, transformation matrices, control over interpolation, basic colour management) there has been some very strange design decisions made such as how masks / alpha channels are stored. This is where using plugins works well and any developer creating an application that has more than basic graphics requirements should invest in either the MBS and / or the Einhuger plug-ins.

Regarding your original query of loading large pictures, this is one area where 64 bit would have potentially given you an easy solution as it would in theory, be possible to allocate the buffers you need. However, If you really want to do this today then you are going to have to build this capability into the core of your application. Peter Stys has already given a good description on what you need to do and appears to be similar to what apps such as Photoshop do.
If you have the MBS plug-ins then there are a lot of functions to allocate pictures, load pictures, save pictures and process pictures involving a memory mapped buffer which our company commissioned Christian to develop. You still need to convert from PictureMBS to a Xojo Picture if you want to draw on the screen or interact with Xojo graphics functions but the answer to that is to rely as little as possible on a Xojo Picture. I have had discussions with Christian in the past to add a function to draw a PictureMBS onto the screen but this is not something that can be done directly today.

Hope this helps.
Kev.