views:

598

answers:

3

I have an Eclipse RCP application that displays a lot (10k+) of small images next to each other, like a film strip. For each image, I am using a SWT Image object. This uses an excessive amount of memory and resources. I am looking for a more efficient way. I thought of taking all of these images and concatenating them by creating an ImageData object of the proper total, concatenated width (with a constant height) and using setPixel() for the rest of the pixels. However, the Palette used in the ImageData constructor I can't figure out.

I also searched for SWT tiling or mosaic functionality to create one image from a group of images, but found nothing.

Any ideas how I can display thousands of small images next to each other efficiently? Please note that once the images are displayed, they are not manipulated, so this is a one-time cost.

A: 

Presumably not every image is visible on screen at any one time? Perhaps a better solution would be to only load the images when they become (or are about to become) visible, disposing of them when they have been scrolled off the screen. Obviously you'd want to keep a few in memory on either side of the current viewport in order to make a smooth transition for the user.

alexmcchessers
How would detect when an image was scrolled off the screen?
Dr. Faust
A: 

I previously worked with a Java application to create photomosaics, and found it very difficult to achieve adequate performance and memory usage using the java imaging (JAI) libraries and SWT. Although we weren't using nearly as many images as you mention, one route was to rely on a utilities outside of java. In particular, you could use ImageMagick command-line utilities to stitch together your mosaic, and the load the completed memory from disk. If you want to get fancy, there is also a C++ API for ImageMagick, which is very efficient in memory.

Scott Wegner
+2  A: 

You can draw directly on the GC (graphics context) of a new (big) image. Having one big Image should result in much less resource usage than thousands of smaller images (each image in SWT keeps some OS graphics object handle)

What you can try is something like this:

  final List<Image> images;
  final Image bigImage = new Image(Display.getCurrent(), combinedWidth, height);
  final GC gc = new GC(bigImage);
  //loop thru all the images while increasing x as necessary:
  int x = 0;
  int y = 0;
  for (Image curImage : images) {
   gc.drawImage(curImage, x, y);
   x += curImage.getBounds().width;
  }
  //very important to dispose GC!!!
                    gc.dispose();
  //now you can use bigImage
Herman Lintvelt