Swift - 图像旋转度数 - 变形结果
Swift - Image rotation in degrees - deformed result
我在 Swift 中找到了几种按度数旋转图像的方法,但没有一种方法始终有效。我想将图像向左或向右旋转 90 度。我认为最好的是这个:
class func imageRotated(_ oldImage: UIImage, byDegrees degrees: CGFloat) -> UIImage {
//Calculate the size of the rotated view's containing box for our drawing space
let rotatedViewBox: UIView = UIView(frame: CGRect(x: 0, y: 0, width: oldImage.size.width, height: oldImage.size.height))
let t: CGAffineTransform = CGAffineTransform(rotationAngle: degrees * CGFloat(M_PI / 180))
rotatedViewBox.transform = t
let rotatedSize: CGSize = rotatedViewBox.frame.size
//Create the bitmap context
UIGraphicsBeginImageContext(rotatedSize)
let bitmap: CGContext = UIGraphicsGetCurrentContext()!
//Move the origin to the middle of the image so we will rotate and scale around the center.
bitmap.translateBy(x: rotatedSize.width / 2, y: rotatedSize.height / 2)
//Rotate the image context
bitmap.rotate(by: (degrees * CGFloat(M_PI / 180)))
//Now, draw the rotated/scaled image into the context
bitmap.scaleBy(x: 1.0, y: -1.0)
bitmap.draw(oldImage.cgImage!, in: CGRect(x: -oldImage.size.width / 2, y: -oldImage.size.height / 2, width: oldImage.size.width, height: oldImage.size.height))
let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return newImage
}
它可以正常工作,可以做我想做的事,但有几次它会变形结果,所以它不会旋转,只是图像大小发生变化,或者它旋转 180 度,图像大小发生变化。
轮换前:
旋转后(菜单丢失,因为它自动隐藏):
奇怪的是我拍人像的时候会出现这种情况。当我拍摄横向照片时,旋转效果很好(即使我尝试旋转几次,即使我从横向旋转到纵向然后再旋转到横向,它仍然可以正常工作)。
我看到一些关于自动布局约束问题的讨论,但我不确定这是否是我的问题以及为什么它在某些情况下有效而在某些情况下无效。我在集合单元格中有照片,每个单元格都有第一个 UIScrollView,而在 UIScrollView 中有带照片的 UIImageView。所有约束都设置为边界。
如果有帮助,我只想旋转 90 或 -90 度。这可能会使方法更简单并且更容易修复。
感谢您的帮助。
实际上最简单也可能是最好的方法是创建一个视图,在其上放置一个图像视图,旋转图像视图,调整超级视图的大小并创建该视图的屏幕截图。
您实际上并没有在视图层次结构中添加这些视图,您只是使用它们轻松生成图像。
为什么这是一个很好的程序,因为UIView
已经编写了所有代码以完全支持核心图形。所以完全没有缺点,你可以肯定这些程序已经被苹果打磨过了。
所以试试这个:
func transformImage(image: UIImage?, transform: CGAffineTransform) -> UIImage? {
guard let image = image else {
return nil
}
let view = UIView(frame: CGRect.zero)
let imageView = UIImageView(image: image)
imageView.transform = transform
view.addSubview(imageView)
imageView.frame.origin = CGPoint.zero
view.frame = CGRect(x: 0.0, y: 0.0, width: imageView.frame.size.width, height: imageView.frame.size.height)
UIGraphicsBeginImageContext(view.frame.size)
view.layer.render(in: UIGraphicsGetCurrentContext()!)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
if let cgImage = newImage?.cgImage {
return UIImage(cgImage: cgImage)
} else {
return nil
}
}
至于您程序中的问题,很可能是因为您放弃了 UIImage
的转换。 CGImage
基本上是原始图像表示,它不知道旋转。 UIImage
确实有 imageOrientation
。因此,您需要做的是从图像方向生成变换矩阵并使用它来解决这个问题。
因此,当您使用设备拍摄图像时,CGImage
将始终具有相同的方向(横向左侧或右侧)。但是 UIImage
会改变图像方向,然后用于表示。
我在 Swift 中找到了几种按度数旋转图像的方法,但没有一种方法始终有效。我想将图像向左或向右旋转 90 度。我认为最好的是这个:
class func imageRotated(_ oldImage: UIImage, byDegrees degrees: CGFloat) -> UIImage {
//Calculate the size of the rotated view's containing box for our drawing space
let rotatedViewBox: UIView = UIView(frame: CGRect(x: 0, y: 0, width: oldImage.size.width, height: oldImage.size.height))
let t: CGAffineTransform = CGAffineTransform(rotationAngle: degrees * CGFloat(M_PI / 180))
rotatedViewBox.transform = t
let rotatedSize: CGSize = rotatedViewBox.frame.size
//Create the bitmap context
UIGraphicsBeginImageContext(rotatedSize)
let bitmap: CGContext = UIGraphicsGetCurrentContext()!
//Move the origin to the middle of the image so we will rotate and scale around the center.
bitmap.translateBy(x: rotatedSize.width / 2, y: rotatedSize.height / 2)
//Rotate the image context
bitmap.rotate(by: (degrees * CGFloat(M_PI / 180)))
//Now, draw the rotated/scaled image into the context
bitmap.scaleBy(x: 1.0, y: -1.0)
bitmap.draw(oldImage.cgImage!, in: CGRect(x: -oldImage.size.width / 2, y: -oldImage.size.height / 2, width: oldImage.size.width, height: oldImage.size.height))
let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return newImage
}
它可以正常工作,可以做我想做的事,但有几次它会变形结果,所以它不会旋转,只是图像大小发生变化,或者它旋转 180 度,图像大小发生变化。
轮换前:
旋转后(菜单丢失,因为它自动隐藏):
奇怪的是我拍人像的时候会出现这种情况。当我拍摄横向照片时,旋转效果很好(即使我尝试旋转几次,即使我从横向旋转到纵向然后再旋转到横向,它仍然可以正常工作)。
我看到一些关于自动布局约束问题的讨论,但我不确定这是否是我的问题以及为什么它在某些情况下有效而在某些情况下无效。我在集合单元格中有照片,每个单元格都有第一个 UIScrollView,而在 UIScrollView 中有带照片的 UIImageView。所有约束都设置为边界。
如果有帮助,我只想旋转 90 或 -90 度。这可能会使方法更简单并且更容易修复。
感谢您的帮助。
实际上最简单也可能是最好的方法是创建一个视图,在其上放置一个图像视图,旋转图像视图,调整超级视图的大小并创建该视图的屏幕截图。
您实际上并没有在视图层次结构中添加这些视图,您只是使用它们轻松生成图像。
为什么这是一个很好的程序,因为UIView
已经编写了所有代码以完全支持核心图形。所以完全没有缺点,你可以肯定这些程序已经被苹果打磨过了。
所以试试这个:
func transformImage(image: UIImage?, transform: CGAffineTransform) -> UIImage? {
guard let image = image else {
return nil
}
let view = UIView(frame: CGRect.zero)
let imageView = UIImageView(image: image)
imageView.transform = transform
view.addSubview(imageView)
imageView.frame.origin = CGPoint.zero
view.frame = CGRect(x: 0.0, y: 0.0, width: imageView.frame.size.width, height: imageView.frame.size.height)
UIGraphicsBeginImageContext(view.frame.size)
view.layer.render(in: UIGraphicsGetCurrentContext()!)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
if let cgImage = newImage?.cgImage {
return UIImage(cgImage: cgImage)
} else {
return nil
}
}
至于您程序中的问题,很可能是因为您放弃了 UIImage
的转换。 CGImage
基本上是原始图像表示,它不知道旋转。 UIImage
确实有 imageOrientation
。因此,您需要做的是从图像方向生成变换矩阵并使用它来解决这个问题。
因此,当您使用设备拍摄图像时,CGImage
将始终具有相同的方向(横向左侧或右侧)。但是 UIImage
会改变图像方向,然后用于表示。