gnustep-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: NSImage and ICNS


From: Eric Wasylishen
Subject: Re: NSImage and ICNS
Date: Thu, 9 Jun 2011 09:42:12 -0600

(moved to gnustep-dev)

On 2011-06-09, at 1:36 AM, Dr. H. Nikolaus Schaller wrote:


Am 09.06.2011 um 09:28 schrieb Dr. H. Nikolaus Schaller:


Am 09.06.2011 um 09:15 schrieb Eric Wasylishen:


From some brief experimentation on Cocoa, it seems that ICNS files are given special treatment: If you create an NSImageView with an NSImage loaded from an ICNS file, resizing the image view will cause the best-sized representations to be used (the smallest one which is larger than or equal the destination size). However, if you do the same thing with either of the TIFF files I posted above, only the first sub-image in the TIFF is used. I'm not sure why this is; it seems like a bug in Cocoa.

I am not sure if Cocoa handles multi-image TIFF files at all and always uses the first (sub)image.


I should point out that according to the documentation, the way that NSImage picks a best representation when there are representations with different point sizes (as is the case with icons) is undefined.

It is described here (section "How an Image Representation Is Chosen"):

http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/CocoaDrawingGuide/Images/Images.html

Right. The instructions there have to be read very carefully, though - by "resolution" they are referring to DPI. If the representations have the same DPI, color depth, and color space, but different dimensions (in points), by following that set of instructions the best representation would be "operating-system dependent". At least, that's how I interpret it.

and done by -bestRepresentation:

http://developer.apple.com/library/mac/#documentation/cocoa/Reference/ApplicationKit/Classes/NSImage_Class/DeprecationAppendix/AppendixADeprecatedAPI.html%23//apple_ref/occ/instm/NSImage/bestRepresentationForDevice:

But beware: it is deprecated in 10.6.


One potential solution I have in mind is modifying -[NSImageCell drawInteriorWithFrame:] so it manually chooses an image rep based on the size that the cell is going to be drawn in. That's only the first thing that came to mind, though; it probably needs some closer investigation.

On Cocoa it is fully automatic within NSImage (i.e. it scans and scores all image reps it knows) so there is no special case to be considered in any NSView or NSCell.

Yes, but as far as I know, the rect given to -[NSImage drawInRect:...] has no influence on the choice of representation to use to draw with (in either Cocoa or GNUstep).  If we have a TIFF or ICNS file with different versions of an icon at 16x16, 32x32, 128x128, etc, and if we want to draw that in an NSImageView, and we want the frame size of the image view to determine which image rep is chosen, we can't just rely on the built-in image rep matching of NSImage. That's why I was suggesting we might need to implement a special case in NSImageCell which uses the frame to draw in to choose an image rep.

Hm. Why should the frame size influence resolution? The screen resolution doesn't change if you make windows smaller or larger. The scoring mechanism should find the best representation for a given pixel density of the screen.


I just meant the frame size could influence representation choice when the NSImage is an "icon-like" image (it has representations at different sizes like 16, 32, 128.) These could all be at the same resolution (72dpi).

This may only have an influence if you want to scale (enlarge) the image. I think this should be embedded in

drawInRect:fromRect:operation:fraction:

which can choose any representation that best its the scaled rect (I have no idea how that works internally).

Indeed, just experimenting on Cocoa, and drawing the ICNS image I posted earlier, simply calling drawInRect:fromRect:operation:fraction: with different destination rect sizes, I can get it to use different representations. So we shouldn't need any special cases in NSImageCell to duplicate this behaviour like I was thinking about earlier. 

In that case we must enlarge a finer resolution than the default. I just found that 10.6 appears to address this with a new method:



Did you mean bestRepresentationForRect:context:hints: ? That looks like exactly what we need to implement. I just tested it a bit and the size of the first parameter is used in choosing the rep to return.

And one more thought about the reason why it is as it is. This may be the way Postscript/PDF works. There, you have to choose some bitmap that you must encode into the PDF file (I think in TIFF). Later the CTM is set controlling scaling etc. and the bitmap is stamped on paper. If the same image is drawn several times in different scales, only the CTM changes. This explains why choosing the best representation must know the device resolution in advance and why scaling appears not to influence the choice of a representation.

But this is only a theory...

I think that's right.

So in summary, I think we just need to implement -bestRepresentationForRect:context:hints:, which looks for a rep which is equal to or larger in size than the given rect's size. Next we need to modify -drawInRect:... to call this new bestRepresentationForRect:context:hints: method instead of -bestRepresentationForDevice:.

Cheers,
Eric

reply via email to

[Prev in Thread] Current Thread [Next in Thread]