mirror of
https://github.com/arsenetar/dupeguru-cocoa.git
synced 2024-12-06 12:49:02 +00:00
114 lines
3.9 KiB
Objective-C
114 lines
3.9 KiB
Objective-C
// Created by Scott Stevenson on 9/28/07.
|
|
//
|
|
// Personal site: http://theocacao.com/
|
|
// Post for this sample: http://theocacao.com/document.page/497
|
|
//
|
|
// The code in this project is intended to be used as a learning
|
|
// tool for Cocoa programmers. You may freely use the code in
|
|
// your own programs, but please do not use the code as-is in
|
|
// other tutorials.
|
|
|
|
#import "NSImageAdditions.h"
|
|
|
|
|
|
@implementation NSImage (Extras)
|
|
|
|
- (NSImage*)imageByScalingProportionallyToSize:(NSSize)targetSize
|
|
{
|
|
NSImage* sourceImage = self;
|
|
NSImage* newImage = nil;
|
|
|
|
if ([sourceImage isValid])
|
|
{
|
|
NSSize imageSize = [sourceImage size];
|
|
CGFloat width = imageSize.width;
|
|
CGFloat height = imageSize.height;
|
|
|
|
CGFloat targetWidth = targetSize.width;
|
|
CGFloat targetHeight = targetSize.height;
|
|
|
|
// scaleFactor will be the fraction that we'll
|
|
// use to adjust the size. For example, if we shrink
|
|
// an image by half, scaleFactor will be 0.5. the
|
|
// scaledWidth and scaledHeight will be the original,
|
|
// multiplied by the scaleFactor.
|
|
//
|
|
// IMPORTANT: the "targetHeight" is the size of the space
|
|
// we're drawing into. The "scaledHeight" is the height that
|
|
// the image actually is drawn at, once we take into
|
|
// account the ideal of maintaining proportions
|
|
|
|
CGFloat scaleFactor = 0.0;
|
|
CGFloat scaledWidth = targetWidth;
|
|
CGFloat scaledHeight = targetHeight;
|
|
|
|
NSPoint thumbnailPoint = NSMakePoint(0,0);
|
|
|
|
// since not all images are square, we want to scale
|
|
// proportionately. To do this, we find the longest
|
|
// edge and use that as a guide.
|
|
|
|
if ( NSEqualSizes( imageSize, targetSize ) == NO )
|
|
{
|
|
// use the longeset edge as a guide. if the
|
|
// image is wider than tall, we'll figure out
|
|
// the scale factor by dividing it by the
|
|
// intended width. Otherwise, we'll use the
|
|
// height.
|
|
|
|
CGFloat widthFactor = targetWidth / width;
|
|
CGFloat heightFactor = targetHeight / height;
|
|
|
|
if ( widthFactor < heightFactor )
|
|
scaleFactor = widthFactor;
|
|
else
|
|
scaleFactor = heightFactor;
|
|
|
|
// ex: 500 * 0.5 = 250 (newWidth)
|
|
|
|
scaledWidth = width * scaleFactor;
|
|
scaledHeight = height * scaleFactor;
|
|
|
|
// center the thumbnail in the frame. if
|
|
// wider than tall, we need to adjust the
|
|
// vertical drawing point (y axis)
|
|
|
|
if ( widthFactor < heightFactor )
|
|
thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
|
|
|
|
else if ( widthFactor > heightFactor )
|
|
thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
|
|
}
|
|
|
|
|
|
// create a new image to draw into
|
|
newImage = [[NSImage alloc] initWithSize:targetSize];
|
|
|
|
// once focus is locked, all drawing goes into this NSImage instance
|
|
// directly, not to the screen. It also receives its own graphics
|
|
// context.
|
|
//
|
|
// Also, keep in mind that we're doing this in a background thread.
|
|
// You only want to draw to the screen in the main thread, but
|
|
// drawing to an offscreen image is (apparently) okay.
|
|
|
|
[newImage lockFocus];
|
|
|
|
NSRect thumbnailRect;
|
|
thumbnailRect.origin = thumbnailPoint;
|
|
thumbnailRect.size.width = scaledWidth;
|
|
thumbnailRect.size.height = scaledHeight;
|
|
|
|
[sourceImage drawInRect: thumbnailRect
|
|
fromRect: NSZeroRect
|
|
operation: NSCompositeSourceOver
|
|
fraction: 1.0];
|
|
|
|
[newImage unlockFocus];
|
|
|
|
}
|
|
|
|
return [newImage autorelease];
|
|
}
|
|
|
|
@end |