-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Expand file tree
/
Copy pathUIImage+Extensions.swift
More file actions
131 lines (116 loc) · 5.03 KB
/
UIImage+Extensions.swift
File metadata and controls
131 lines (116 loc) · 5.03 KB
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
//
// UIImage+ResetOrientation.swift
// YPImagePicker
//
// Created by Sacha DSO on 20/02/2018.
// Copyright © 2018 Yummypets. All rights reserved.
//
import UIKit
internal extension UIImage {
func resized(to size: CGSize) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(size, false, scale)
defer { UIGraphicsEndImageContext() }
draw(in: CGRect(origin: .zero, size: size))
return UIGraphicsGetImageFromCurrentImageContext()
}
// Kudos to Trevor Harmon and his UIImage+Resize category from
// which this code is heavily inspired.
func resetOrientation() -> UIImage {
// Image has no orientation, so keep the same
if imageOrientation == .up {
return self
}
// Process the transform corresponding to the current orientation
var transform = CGAffineTransform.identity
switch imageOrientation {
case .down, .downMirrored: // EXIF = 3, 4
transform = transform.translatedBy(x: size.width, y: size.height)
transform = transform.rotated(by: CGFloat(Double.pi))
case .left, .leftMirrored: // EXIF = 6, 5
transform = transform.translatedBy(x: size.width, y: 0)
transform = transform.rotated(by: CGFloat(Double.pi / 2))
case .right, .rightMirrored: // EXIF = 8, 7
transform = transform.translatedBy(x: 0, y: size.height)
transform = transform.rotated(by: -CGFloat((Double.pi / 2)))
default:
()
}
switch imageOrientation {
case .upMirrored, .downMirrored: // EXIF = 2, 4
transform = transform.translatedBy(x: size.width, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
case .leftMirrored, .rightMirrored: // EXIF = 5, 7
transform = transform.translatedBy(x: size.height, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
default:
()
}
// Draw a new image with the calculated transform
let context = CGContext(data: nil,
width: Int(size.width),
height: Int(size.height),
bitsPerComponent: cgImage!.bitsPerComponent,
bytesPerRow: 0,
space: cgImage!.colorSpace!,
bitmapInfo: cgImage!.bitmapInfo.rawValue)
context?.concatenate(transform)
switch imageOrientation {
case .left, .leftMirrored, .right, .rightMirrored:
context?.draw(cgImage!, in: CGRect(x: 0, y: 0, width: size.height, height: size.width))
default:
context?.draw(cgImage!, in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
}
if let newImageRef = context?.makeImage() {
let newImage = UIImage(cgImage: newImageRef)
return newImage
}
// In case things go wrong, still return self.
return self
}
// Reduce image size further if needed targetImageSize is capped.
func resizedImageIfNeeded() -> UIImage {
if case let YPImageSize.cappedTo(size: capped) = YPConfig.targetImageSize {
let size = cappedSize(for: self.size, cappedAt: capped)
if let resizedImage = self.resized(to: size) {
return resizedImage
}
}
return self
}
fileprivate func cappedSize(for size: CGSize, cappedAt: CGFloat) -> CGSize {
var cappedWidth: CGFloat = 0
var cappedHeight: CGFloat = 0
if size.width > size.height {
// Landscape
let heightRatio = size.height / size.width
cappedWidth = min(size.width, cappedAt)
cappedHeight = cappedWidth * heightRatio
} else if size.height > size.width {
// Portrait
let widthRatio = size.width / size.height
cappedHeight = min(size.height, cappedAt)
cappedWidth = cappedHeight * widthRatio
} else {
// Squared
cappedWidth = min(size.width, cappedAt)
cappedHeight = min(size.height, cappedAt)
}
return CGSize(width: cappedWidth, height: cappedHeight)
}
func toCIImage() -> CIImage? {
return self.ciImage ?? CIImage(cgImage: self.cgImage!)
}
func withInsets(_ insets: UIEdgeInsets, color: UIColor = .clear) -> UIImage? {
let size = CGSize(
width: 24 + insets.left + insets.right,
height: 17 + insets.top + insets.bottom
)
UIGraphicsBeginImageContextWithOptions(size, false, self.scale)
color.setFill()
UIRectFill(CGRect(origin: .zero, size: size))
self.draw(at: CGPoint(x: insets.left, y: insets.top))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
}