3

I am working on an image-browser app for OS X. It is very similar to QuickLook: you pick a folder, the app displays the first image in it, and you can use the arrow keys to quickly move to the next/previous picture.

Now, I'm testing my app with RAW format pictures that are very large: for instance, I have a .cr2 file that is almost 25 MB. NSImageView takes 5 to 10 seconds to load this kind of pictures. I would like the transition from a picture to the next to be as fast as possible. I see 2 options:

1) load the picture incrementally and display it as it is being loaded (either by chunks or by gradually improving resolution). Is it possible to do this? How?

2) scale down pictures so that NSImageView can display them instantly (I don't care too much about resolution). How fast can you scale a picture?

Thanks!

Diego
  • 577
  • 4
  • 14
  • Maybe create something like a library (like iPhoto or aperture does) and either save the images in there or if that's not possible just the paths to all already viewed pictures. In any case you can save thumbnails in there for each picture (like a cache). The file name is of course not enough, you'd need a hash, since the user might change the image but keep the file name. (Or you use the new Finder API to get notified if an object at some path changes, but I'm not familiar with that). This is all a little hacky and more a workaround than a solution but it might a starting point ... – HAS Dec 02 '14 at 18:21
  • 1
    Another option (or an extension) would be to downscale all images in a folder (or those which are most likely next chosen by the user) and save them in a DB. You could do that in a background thread so that the interface is always responsible. I think letting NSImageView resize the image is the worst solution since it keeps your whole image in memory and (if I remember correctly) the loading of the image into the view is a blocking operation. – HAS Dec 02 '14 at 18:26
  • 1
    @HAS yeah, my solution right now is: when the user picks a folder, if there are any large images inside the folder I ask the user if they want to pre-process the images. If they accept, I create a temporary folder with scaled-down images. If not, the app just takes a while to display the larger images. It is not very clean, that's why I'm trying to find a better solution. – Diego Dec 02 '14 at 18:40

2 Answers2

2

That 5-10 seconds is probably due to converting the RAW data to a format that NSImageView can display. Just reading 25MB from the disk is going to impose a delay, and processing all that data will add more. Whenever possible, you'll want to avoid that conversion process.

CR2 files can contain small JPEG preview images, and it'd surely be a lot faster to read a small thumbnail than to convert a 25MB file. The web page Inside the Canon RAW format version 2 has a lot of information about the structure of CR2 files that should help you find any thumbnail images. Another page, Extracting thumbnails from camera RAW files (.CR2 and .NEF) with PHP, demonstrates how to extract thumbnail images from your CR2 files.

If the thumbnail images included in the file isn't sufficient for your needs, you'll have to either let NSImageView or some other component convert the file for you, or else write your own converter. The CR2 format information from the first link above should help you find the RAW data itself, and you could potentially construct a preview image more quickly than converting the whole thing by reading only every nth line of pixels (and then using only every nth pixel from the lines you do read). See section 4 in the Extracting thumbnails... document for help interpreting the RAW data.

Caleb
  • 124,013
  • 19
  • 183
  • 272
  • Hey thanks! that's a lot of useful info. Only problem is I will probably need to do separate things for CR2, CRW, NEF, etc. I'll test with CR2 and see how it goes. Thanks! – Diego Dec 02 '14 at 20:00
1

You can preload previous and next images while a given image is displayed. You just have to construct a table of 3 NSImage, shift them as needed and load a new one. So that your images were almost all the time already loaded before displaying them. Of course, this will not work if you press keys very fast. You can also preload any number of image if needed. Remember that NSImage has a caching mechanism inside.

Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69
  • thanks. I tried something like this a while ago but I ran into some problems. Gonna try again and see how it works! – Diego Dec 02 '14 at 19:02