-
Notifications
You must be signed in to change notification settings - Fork 4
/
UIImage+Resize.swift
179 lines (157 loc) · 6.33 KB
/
UIImage+Resize.swift
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
//
// UIImage+Resize.swift
//
// Originally created by Trevor Harmon on 8/5/09
// Translated to Swift by Daniel Park on 2/5/15.
//
// Free for personal or commercial use, with or without modification
// No warranty is expressed or implied
import Foundation
import UIKit
extension UIImage {
// Returns a copy of this image that is cropped to the given bounds.
// The bounds will be adjusted using CGRectIntegral.
// This method ignores the image's imageOrientation setting.
func croppedImage(bounds: CGRect) -> UIImage {
let imageRef:CGImageRef = CGImageCreateWithImageInRect(self.CGImage, bounds)
return UIImage(CGImage: imageRef)!
}
func thumbnailImage(
thumbnailSize: Int,
transparentBorder borderSize:Int,
cornerRadius:Int,
interpolationQuality quality:CGInterpolationQuality
) -> UIImage {
var resizedImage:UIImage = self.resizedImageWithContentMode(
.ScaleAspectFill,
bounds: CGSizeMake(CGFloat(thumbnailSize), CGFloat(thumbnailSize)),
interpolationQuality: quality
)
var cropRect:CGRect = CGRectMake(
round((resizedImage.size.width - CGFloat(thumbnailSize))/2),
round((resizedImage.size.height - CGFloat(thumbnailSize))/2),
CGFloat(thumbnailSize),
CGFloat(thumbnailSize)
)
var croppedImage:UIImage = resizedImage.croppedImage(cropRect)
return croppedImage
}
// Returns a rescaled copy of the image, taking into account its orientation
// The image will be scaled disproportionately if necessary to fit the bounds specified by the parameter
func resizedImage(newSize:CGSize, interpolationQuality quality:CGInterpolationQuality) -> UIImage {
var drawTransposed:Bool
switch(self.imageOrientation) {
case .Left:
fallthrough
case .LeftMirrored:
fallthrough
case .Right:
fallthrough
case .RightMirrored:
drawTransposed = true
break
default:
drawTransposed = false
break
}
return self.resizedImage(
newSize,
transform: self.transformForOrientation(newSize),
drawTransposed: drawTransposed,
interpolationQuality: quality
)
}
func resizedImageWithContentMode(
contentMode:UIViewContentMode,
bounds:CGSize,
interpolationQuality quality:CGInterpolationQuality
) -> UIImage {
var horizontalRatio:CGFloat = bounds.width / self.size.width
var verticalRatio:CGFloat = bounds.height / self.size.height
var ratio:CGFloat = 1
switch(contentMode) {
case .ScaleAspectFill:
ratio = max(horizontalRatio, verticalRatio)
break
case .ScaleAspectFit:
ratio = min(horizontalRatio, verticalRatio)
break
default:
println("Unsupported content mode \(contentMode)")
}
var newSize:CGSize = CGSizeMake(self.size.width * ratio, self.size.height * ratio)
return self.resizedImage(newSize, interpolationQuality: quality)
}
func resizedImage(
newSize:CGSize,
transform:CGAffineTransform,
drawTransposed transpose:Bool,
interpolationQuality quality:CGInterpolationQuality
) -> UIImage {
var newRect:CGRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, newSize.height))
var transposedRect:CGRect = CGRectMake(0, 0, newRect.size.height, newRect.size.width)
var imageRef:CGImageRef = self.CGImage
// build a context that's the same dimensions as the new size
var bitmap:CGContextRef = CGBitmapContextCreate(
nil,
UInt(newRect.size.width),
UInt(newRect.size.height),
CGImageGetBitsPerComponent(imageRef),
0,
CGImageGetColorSpace(imageRef),
CGImageGetBitmapInfo(imageRef)
)
// rotate and/or flip the image if required by its orientation
CGContextConcatCTM(bitmap, transform)
// set the quality level to use when rescaling
CGContextSetInterpolationQuality(bitmap, quality)
// draw into the context; this scales the image
CGContextDrawImage(bitmap, transpose ? transposedRect : newRect, imageRef)
// get the resized image from the context and a UIImage
var newImageRef:CGImageRef = CGBitmapContextCreateImage(bitmap)
var newImage:UIImage = UIImage(CGImage: newImageRef)!
return newImage
}
func transformForOrientation(newSize:CGSize) -> CGAffineTransform {
var transform:CGAffineTransform = CGAffineTransformIdentity
switch (self.imageOrientation) {
case .Down: // EXIF = 3
fallthrough
case .DownMirrored: // EXIF = 4
transform = CGAffineTransformTranslate(transform, newSize.width, newSize.height)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
break
case .Left: // EXIF = 6
fallthrough
case .LeftMirrored: // EXIF = 5
transform = CGAffineTransformTranslate(transform, newSize.width, 0)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
break
case .Right: // EXIF = 8
fallthrough
case .RightMirrored: // EXIF = 7
transform = CGAffineTransformTranslate(transform, 0, newSize.height)
transform = CGAffineTransformRotate(transform, -CGFloat(M_PI_2))
break
default:
break
}
switch(self.imageOrientation) {
case .UpMirrored: // EXIF = 2
fallthrough
case .DownMirrored: // EXIF = 4
transform = CGAffineTransformTranslate(transform, newSize.width, 0)
transform = CGAffineTransformScale(transform, -1, 1)
break
case .LeftMirrored: // EXIF = 5
fallthrough
case .RightMirrored: // EXIF = 7
transform = CGAffineTransformTranslate(transform, newSize.height, 0)
transform = CGAffineTransformScale(transform, -1, 1)
break
default:
break
}
return transform
}
}