Re: NSImage rescaling
Re: NSImage rescaling
- Subject: Re: NSImage rescaling
- From: "David Piasecki" <email@hidden>
- Date: Tue, 8 Feb 2005 09:10:35 -0800
John,
I think you're right. I sat down last night and created an XCode project dedicated to solving this mystery. I found out that Apple's documentation on NSScaleProportionally isn't exactly complete, as you demonstrated in your example as well. The documentation states that "
If the image is too large, it shrinks to fit inside the frame. If the image is too small, it expands. The proportions of the image are preserved."
As you noted the image actually expands, but only as large as its original size and no further, which I believe may not be the full-scale size of the image. It may be the size first set with the setSize method. That's the behavior I was observing.
So I tried NSScaleToFit at home last night, and it seemed to work exactly the way I had envisioned. To get proportionality, I'm just going to ensure that the size remains proportional to the original image size in my code. I'm a little frustrated since I wasted about 4 hours trying to figure out why NSScaleProportionally doesn't behave the way it's stated to in the documentation, thinking all along that I was doing something wrong. But that's just another example of my frustration with Apple's documentation. It still needs a lot of work. I hope the folks at Apple are hearing this ;) 4 hours of lost work due to incomplete documentation is 4 hours less code written and 4 hours fewer features for applications that may entice people to switch to the Mac... or worse... the lost development time may --GASP!-- cause developers to choose to switch back to Windoze.
Anyway, thanks very much for your help,
David
On Feb 7, 2005, at 8:28 PM, John Pannell wrote:
Hi David-
I think you may be bumping up against a limitation of NSImageView in
regard to NSScaleProportionally. In my experience, it will shrink an
image proportionally, but not grow one. Once you reach the original
size of the image, the image just sits centered, actual size, in the
growing view.
Not knowing the mechanics of your app, I don't know if the following
snippet will work for you or not. I have an NSImageView subclass that
sits in an NSScrollView, an have provided the user with a pop-up control
on the scroll view to select scaling for the image (much like Freehand,
Photoshop, etc.). In this case, the NSImageView subclass uses
NSScaleToFit, looks at its superview to determine the target size, and
then ensures that it resizes itself to the same aspect ratio as the
image. This prevents you from having to monkey with another copy of the
image, etc. In the code below, -1 is sent in as the "proportionally
scale to fit", otherwise scale is a float representing the percent
scale. The code grows the NSImageView (subclass) - it never does
anything with the NSImage.
You can see it in action:
http://www.positivespinmedia.com/shareware/NetScrape/
It should also be noted that enlarging an image is by nature going to
result in a degraded image, since you now have less image data than you
have image. Hope this helps!
@implementation PSMFlippedImageView
- (id)initWithFrame:(NSRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self setImageScaling:NSScaleToFit];
}
return self;
}
- (BOOL)isFlipped
{
return YES;
}
- (void)scaleFrameBy:(float)scale
{
NSSize imageSize = [[self image] size];
float heightFactor, widthFactor;
NSAffineTransform *at = [NSAffineTransform transform];
if(scale == -1.0){
// size to fit
heightFactor = [[self superview]
frame].size.height/imageSize.height;
widthFactor = [[self superview]
frame].size.width/imageSize.width;
if(heightFactor > widthFactor){
scale = widthFactor;
} else {
scale = heightFactor;
}
}
[at scaleBy:scale];
[self setFrameSize:[at transformSize:imageSize]];
[self setNeedsDisplay:YES];
}
- (void)resizeWithOldSuperviewSize:(NSSize)oldFrameSize
{
// override to prevent the stretching of the image. No
implementation needed.
}
@end
John
On Feb 7, 2005, at 3:57 PM, David Piasecki wrote:
I've been reading around online to try and get to the bottom of what
seems to be a common problem. I'm scaling an NSImage object using the
following code:
NSImage *scaledImage = [image copy];
[scaledImage setScalesWhenResized:YES];
NSSize imageSize = [scaledImage size];
[scaledImage setSize:NSMakeSize(imageSize.width*zoom,
imageSize.height*zoom)];
[imageView setImage:scaledImage];
[scaledImage release];
This works well; however, it is incredibly slow when the image gets
very large. So rather than copy the image every time I want to enlarge
or shrink the image in my NSImageView, I want the image to
automatically rescale itself. So I decided to manually change the size
of my NSImageView object and set the scale property to
NSScaleProportionally. This doesn't appear to have any effect.
Although the NSImageView size changes, the NSImage displayed remains
the same size unless I copy the image and call [imageView
setImage:scaledImage] again as in the code above. Another behavior
I've observed in different attempts to solve this problem is to have
the NSImage be displayed at a very poor resolution after zooming out
and then trying to zoom back in again since NSImage's setSize method
seems to cause the loss of information.
I'm sure this is really simple and that I'm going about it the wrong
way, so I'd really appreciate it if someone could help by explaining
how to have one image and simply scale it up or down based on the size
of the NSImageView object which contains it.
Thanks,
David _______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
dia.com
This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden