88import UIKit
99import NitroModules
1010
11+ private func roundedUpPixelDimension( _ value: CGFloat ) -> CGFloat {
12+ let rounded = round ( value)
13+ if abs ( value - rounded) < 0.0001 {
14+ return rounded
15+ }
16+ return ceil ( value)
17+ }
18+
1119/**
1220 * A protocol that represents a native image.
1321 * This can be used to downcast from `HybridImageSpec`
@@ -63,20 +71,25 @@ public extension NativeImage {
6371 return HybridImage ( uiImage: rotated)
6472 } else {
6573 // Slow path: we actually rotate using UIGraphicsImageRenderer
66- let renderer = UIGraphicsImageRenderer ( size: uiImage. size)
74+ let radians = degrees * . pi / 180
75+ let sourceSize = uiImage. size
76+ let sourceRect = CGRect ( origin: . zero, size: sourceSize)
77+ let rotatedRect = sourceRect. applying ( CGAffineTransform ( rotationAngle: radians) )
78+ let outputSize = CGSize ( width: roundedUpPixelDimension ( abs ( rotatedRect. width) ) ,
79+ height: roundedUpPixelDimension ( abs ( rotatedRect. height) ) )
80+ let format = UIGraphicsImageRendererFormat ( )
81+ format. scale = 1
82+ let renderer = UIGraphicsImageRenderer ( size: outputSize, format: format)
6783 let rotatedImage = renderer. image { context in
68- let width = uiImage. size. width
69- let height = uiImage. size. height
7084 // 1. Move to the center of the image so our origin is the center
71- context. cgContext. translateBy ( x: width / 2 , y: height / 2 )
85+ context. cgContext. translateBy ( x: outputSize . width / 2 , y: outputSize . height / 2 )
7286 // 2. Rotate by the given radians
73- let radians = degrees * . pi / 180
7487 context. cgContext. rotate ( by: radians)
7588 // 3. Draw the Image offset by half the frame so we counter our center origin from step 1.
76- let rect = CGRect ( x: - ( width / 2 ) ,
77- y: - ( height / 2 ) ,
78- width: width,
79- height: height)
89+ let rect = CGRect ( x: - ( sourceSize . width / 2 ) ,
90+ y: - ( sourceSize . height / 2 ) ,
91+ width: sourceSize . width,
92+ height: sourceSize . height)
8093 uiImage. draw ( in: rect)
8194 }
8295 return HybridImage ( uiImage: rotatedImage)
@@ -97,7 +110,9 @@ public extension NativeImage {
97110 }
98111 let targetSize = CGSize ( width: width, height: height)
99112
100- let renderer = UIGraphicsImageRenderer ( size: targetSize)
113+ let format = UIGraphicsImageRendererFormat ( )
114+ format. scale = 1
115+ let renderer = UIGraphicsImageRenderer ( size: targetSize, format: format)
101116 let resizedImage = renderer. image { context in
102117 let targetRect = CGRect ( origin: . zero, size: targetSize)
103118 uiImage. draw ( in: targetRect)
@@ -124,12 +139,17 @@ public extension NativeImage {
124139 throw RuntimeError . error ( withMessage: " This image does not have an underlying .cgImage! " )
125140 }
126141
127- let targetRect = CGRect ( origin: CGPoint ( x: startX, y: startY) ,
128- size: CGSize ( width: uiImage. size. width, height: uiImage. size. height) )
142+ let scale = uiImage. scale
143+ let targetRect = CGRect ( x: startX * scale,
144+ y: startY * scale,
145+ width: targetWidth * scale,
146+ height: targetHeight * scale) . integral
129147 guard let croppedCgImage = cgImage. cropping ( to: targetRect) else {
130148 throw RuntimeError . error ( withMessage: " Failed to crop CGImage to \( targetRect) ! " )
131149 }
132- let croppedUiImage = UIImage ( cgImage: croppedCgImage)
150+ let croppedUiImage = UIImage ( cgImage: croppedCgImage,
151+ scale: scale,
152+ orientation: uiImage. imageOrientation)
133153 return HybridImage ( uiImage: croppedUiImage)
134154 }
135155
0 commit comments