使用 UIGraphicsImageRenderer 旋转图像?
Rotate image with UIGraphicsImageRenderer?
UIGraphicsImageRenderer
was newly introduced in iOS 10. I was wondering if there is any possibility to rotate an UIImage
with it (any custom angle). I know there is the classic way 与 CGContextRotateCTM
.
查看文档并且由于缺少对此问题的答复,我认为新 UIGraphicsImageRenderer
不可能做到这一点。这是我在一天结束时解决它的方法:
func changeImageRotation(forImage image:UIImage, rotation alpha:CGFloat) -> UIImage{
var newSize:CGSize{
let a = image.size.width
let b = image.size.height
let width = abs(cos(alpha)) * a + abs(sin(alpha)) * b
let height = abs(cos(alpha)) * b + abs(sin(alpha)) * a
return CGSize(width: width, height: height)
}
let size = newSize
let orgin = CGPoint(x: size.width/2, y: size.height/2)
UIGraphicsBeginImageContext(size)
let context = UIGraphicsGetCurrentContext()
context?.translateBy(x: orgin.x, y: orgin.y)
context?.rotate(by: alpha)
context?.draw(image.cgImage!, in: CGRect(origin: CGPoint(x: -orgin.x,y: -orgin.y), size: size))
let newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage!
}
New Size
对应的是在不改变其整体大小的情况下绘制旋转后的图像所需的矩形区域。然后图像旋转并在中心绘制。有关这方面的更多信息,请参阅此 post。
您可以设置 UIGraphicsImageRenderer 来创建图像,然后调用 UIGraphicsGetCurrentContext() 并旋转上下文
let renderer = UIGraphicsImageRenderer(size:sizeOfImage)
let image = renderer.image(actions: { _ in
let context = UIGraphicsGetCurrentContext()
context?.translateBy(x: orgin.x, y: orgin.y)
context?.rotate(by: angle)
context?.draw(image.cgImage!, in: CGRect(origin: CGPoint(x: -orgin.x,y: -orgin.y), size: size))
}
return image
基于@reza23 的回答。你不需要调用 UIGraphicsGetCurrentContext,你可以使用渲染器的上下文。
extension UIImage
{
public func rotate(angle:CGFloat)->UIImage
{
let radians = CGFloat(angle * .pi) / 180.0 as CGFloat
var newSize = CGRect(origin: CGPoint.zero, size: self.size).applying(CGAffineTransform(rotationAngle: radians)).size
// Trim off the extremely small float value to prevent core graphics from rounding it up
newSize.width = floor(newSize.width)
newSize.height = floor(newSize.height)
let renderer = UIGraphicsImageRenderer(size:newSize)
let image = renderer.image
{ rendederContext in
let context = rendederContext.cgContext
//rotate from center
context.translateBy(x: newSize.width/2, y: newSize.height/2)
context.rotate(by: radians)
draw(in: CGRect(origin: CGPoint(x: -self.size.width/2, y: -self.size.height/2), size: size))
}
return image
}
}
UIGraphicsImageRenderer
was newly introduced in iOS 10. I was wondering if there is any possibility to rotate an UIImage
with it (any custom angle). I know there is the classic way 与 CGContextRotateCTM
.
查看文档并且由于缺少对此问题的答复,我认为新 UIGraphicsImageRenderer
不可能做到这一点。这是我在一天结束时解决它的方法:
func changeImageRotation(forImage image:UIImage, rotation alpha:CGFloat) -> UIImage{
var newSize:CGSize{
let a = image.size.width
let b = image.size.height
let width = abs(cos(alpha)) * a + abs(sin(alpha)) * b
let height = abs(cos(alpha)) * b + abs(sin(alpha)) * a
return CGSize(width: width, height: height)
}
let size = newSize
let orgin = CGPoint(x: size.width/2, y: size.height/2)
UIGraphicsBeginImageContext(size)
let context = UIGraphicsGetCurrentContext()
context?.translateBy(x: orgin.x, y: orgin.y)
context?.rotate(by: alpha)
context?.draw(image.cgImage!, in: CGRect(origin: CGPoint(x: -orgin.x,y: -orgin.y), size: size))
let newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage!
}
New Size
对应的是在不改变其整体大小的情况下绘制旋转后的图像所需的矩形区域。然后图像旋转并在中心绘制。有关这方面的更多信息,请参阅此 post。
您可以设置 UIGraphicsImageRenderer 来创建图像,然后调用 UIGraphicsGetCurrentContext() 并旋转上下文
let renderer = UIGraphicsImageRenderer(size:sizeOfImage)
let image = renderer.image(actions: { _ in
let context = UIGraphicsGetCurrentContext()
context?.translateBy(x: orgin.x, y: orgin.y)
context?.rotate(by: angle)
context?.draw(image.cgImage!, in: CGRect(origin: CGPoint(x: -orgin.x,y: -orgin.y), size: size))
}
return image
基于@reza23 的回答。你不需要调用 UIGraphicsGetCurrentContext,你可以使用渲染器的上下文。
extension UIImage
{
public func rotate(angle:CGFloat)->UIImage
{
let radians = CGFloat(angle * .pi) / 180.0 as CGFloat
var newSize = CGRect(origin: CGPoint.zero, size: self.size).applying(CGAffineTransform(rotationAngle: radians)).size
// Trim off the extremely small float value to prevent core graphics from rounding it up
newSize.width = floor(newSize.width)
newSize.height = floor(newSize.height)
let renderer = UIGraphicsImageRenderer(size:newSize)
let image = renderer.image
{ rendederContext in
let context = rendederContext.cgContext
//rotate from center
context.translateBy(x: newSize.width/2, y: newSize.height/2)
context.rotate(by: radians)
draw(in: CGRect(origin: CGPoint(x: -self.size.width/2, y: -self.size.height/2), size: size))
}
return image
}
}