NSImage: Equality and data size

Discussion in 'Mac Programming' started by Nutter, Apr 22, 2007.

  1. Nutter macrumors 6502

    Joined:
    Mar 31, 2005
    Location:
    London, England
    #1
    Two things I'm struggling with:

    - I'm trying to test for equality between two NSImage objects, in terms of the underlying image data used by each one. Unfortunately, NSImage's implementation of isEqual: only tests for pointer equality, as inherited from NSObject.

    The only way I can see of doing this is calling TIFFRepresentation on both images, and comparing the NSData objects. However, since this involves calculating new data (much larger than that used to create the NSImage in the first place!), it seems like an expensive way of testing for equality.

    - I'd like to (very roughly) calculate the memory used by the image. I'm keeping a cache of images, and I want to limit the size of the cache by memory used, rather than number of images.

    I realise these things are tricky because of the magic that NSImage works behind the scenes, but if anyone has any suggestions it would be appreciated!

    All images will be bitmaps.
     
  2. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #2
    I would first compare the number of representations. Then I'd compare the size of each rep, and then finally the actual bytes of each rep.

    Check out NSBitmapImageRep.
     
  3. Nutter thread starter macrumors 6502

    Joined:
    Mar 31, 2005
    Location:
    London, England
    #3
    Thanks! However, is it not the case that when I draw an image, NSImage may decide to render the image to a new representation, and in fact delete the original bitmap representation altogether? I suppose if that's the case it makes it impossible to determine equality based on the data originally used to create the images, so it was a silly question I was asking...

    Perhaps it would be better if I cached the NSData objects that contain the original image data, and create NSImage objects from them when reading from the cache? Any idea how expensive it is to create an NSImage using initWithData:?
     
  4. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #4
    I'm not sure I understand. Are you trying to compare the specific data of the image, or each pixel color by color?
     
  5. Nutter thread starter macrumors 6502

    Joined:
    Mar 31, 2005
    Location:
    London, England
    #5
    My images start out as NSData objects. Some of them may actually contain identical image data, such that [aData isEqualToData:bData] == YES.

    I'm creating NSImage objects from the NSData objects, and I wanted a way to test whether two images were created from equal NSData objects. The reason for wanting this kind of test is that I wanted to keep a cache of images, and I wanted to avoid storing duplicate images in the cache.

    I suspect it might not be possible to do this reliably, as depending on what you do with the NSImage the data representation inside might be rendered and cached in various ways.

    So, I'm now thinking of caching the NSData objects, so that I can reliably test for equality. I can generate NSImage objects as the images are read from the cache.

    I hope that makes some sense...
     
  6. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #6
    Instead of caching the actual NSData, you could store an MD5 hash of it.
     
  7. Nutter thread starter macrumors 6502

    Joined:
    Mar 31, 2005
    Location:
    London, England
    #7
    You mean, cache a checksum along with the NSImage?

    I did consider something like that ... but isn't comparing checksums an unreliable way of testing for equality? Equal objects always have the same checksum, but equal checksums don't necessarily mean equal objects, just probably. Having said that, I'm sure the odds against two non-equal sets of data having equal MD5 checksums is pretty astronomical...

    Do you think it's a bad idea to cache only the data? Is it expensive to create a new NSImage each time the image is read from the cache?
     
  8. Eraserhead macrumors G4

    Eraserhead

    Joined:
    Nov 3, 2005
    Location:
    UK
    #8
    I'd risk it with the hashing, you could store two different hashes and check both for equality, they chances of them both being equal would be even more astronomically small. The point of hashes is that they are different for different files, and they aren't useful otherwise so use them, think about what would go wrong if two images were declared to be equal but weren't.

    If the images were unlikely to be found equal another solution would be to first check the hashes and then if they were equal to check the data itself for equality.
     

Share This Page