forked from ittybittyapps/SliceTool
-
Notifications
You must be signed in to change notification settings - Fork 1
/
NSImage+MGCropExtensions.m
125 lines (106 loc) · 4.27 KB
/
NSImage+MGCropExtensions.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//
// NSImage+MGCropExtensions.m
// ImageCropDemo
//
// Created by Matt Gemmell on 16/03/2006.
//
#import "NSImage+MGCropExtensions.h"
@implementation NSImage (MGCropExtensions)
- (void)drawInRect:(NSRect)dstRect operation:(NSCompositingOperation)op fraction:(float)delta method:(MGImageResizingMethod)resizeMethod
{
float sourceWidth = [self size].width;
float sourceHeight = [self size].height;
float targetWidth = dstRect.size.width;
float targetHeight = dstRect.size.height;
BOOL cropping = !(resizeMethod == MGImageResizeScale);
// Calculate aspect ratios
float sourceRatio = sourceWidth / sourceHeight;
float targetRatio = targetWidth / targetHeight;
// Determine what side of the source image to use for proportional scaling
BOOL scaleWidth = (sourceRatio <= targetRatio);
// Deal with the case of just scaling proportionally to fit, without cropping
scaleWidth = (cropping) ? scaleWidth : !scaleWidth;
// Proportionally scale source image
float scalingFactor, scaledWidth, scaledHeight;
if (scaleWidth) {
scalingFactor = 1.0 / sourceRatio;
scaledWidth = targetWidth;
scaledHeight = round(targetWidth * scalingFactor);
} else {
scalingFactor = sourceRatio;
scaledWidth = round(targetHeight * scalingFactor);
scaledHeight = targetHeight;
}
float scaleFactor = scaledHeight / sourceHeight;
// Calculate compositing rectangles
NSRect sourceRect;
if (cropping) {
float destX, destY;
if (resizeMethod == MGImageResizeCrop) {
// Crop center
destX = round((scaledWidth - targetWidth) / 2.0);
destY = round((scaledHeight - targetHeight) / 2.0);
} else if (resizeMethod == MGImageResizeCropStart) {
// Crop top or left (prefer top)
if (scaleWidth) {
// Crop top
destX = round((scaledWidth - targetWidth) / 2.0);
destY = round(scaledHeight - targetHeight);
} else {
// Crop left
destX = 0.0;
destY = round((scaledHeight - targetHeight) / 2.0);
}
} else if (resizeMethod == MGImageResizeCropEnd) {
// Crop bottom or right
if (scaleWidth) {
// Crop bottom
destX = 0.0;
destY = 0.0;
} else {
// Crop right
destX = round(scaledWidth - targetWidth);
destY = round((scaledHeight - targetHeight) / 2.0);
}
}
sourceRect = NSMakeRect(destX / scaleFactor, destY / scaleFactor,
targetWidth / scaleFactor, targetHeight / scaleFactor);
} else {
sourceRect = NSMakeRect(0, 0, sourceWidth, sourceHeight);
dstRect.origin.x += (targetWidth - scaledWidth) / 2.0;
dstRect.origin.y += (targetHeight - scaledHeight) / 2.0;
dstRect.size.width = scaledWidth;
dstRect.size.height = scaledHeight;
}
[self drawInRect:dstRect fromRect:sourceRect operation:op fraction:delta];
}
- (NSImage *)imageToFitSize:(NSSize)size method:(MGImageResizingMethod)resizeMethod
{
NSImage *result = [[NSImage alloc] initWithSize:size];
// Composite image appropriately
[result lockFocus];
[[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
[self drawInRect:NSMakeRect(0,0,size.width,size.height) operation:NSCompositeSourceOver fraction:1.0 method:resizeMethod];
[result unlockFocus];
return [result autorelease];
}
- (NSImage *)imageCroppedToFitSize:(NSSize)size
{
return [self imageToFitSize:size method:MGImageResizeCrop];
}
- (NSImage *)imageScaledToFitSize:(NSSize)size
{
return [self imageToFitSize:size method:MGImageResizeScale];
}
- (NSImage *)imageCroppedInRect:(NSRect)srcRect {
NSImage *result = [[NSImage alloc] initWithSize:srcRect.size];
NSRect dstRect = NSMakeRect(0.0, 0.0, srcRect.size.width, srcRect.size.height);
[result lockFocus];
//[result lockFocusFlipped:YES];
[[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
[self drawInRect:dstRect fromRect:srcRect operation:NSCompositeSourceOver fraction:1.0];
//[self drawInRect:dstRect fromRect:srcRect operation:NSCompositeSourceOver fraction:1.0 respectFlipped:YES hints:nil];
[result unlockFocus];
return [result autorelease];
}
@end