【问题标题】:Issue in rotating UIImage - IOS/Swift旋转 UIImage 的问题 - IOS/Swift
【发布时间】:2016-08-24 06:13:34
【问题描述】:

为了旋转 UIImage,我使用了从 Internet 下载的扩展程序。在那里,旋转工作正常,但有一些有线行为。

这是扩展代码

import UIKit

extension UIImage {

    public func imageRotatedByDegrees(degrees: CGFloat, flip: Bool) -> UIImage {

        let radiansToDegrees: (CGFloat) -> CGFloat = {
            return $0 * (180.0 / CGFloat(M_PI));
        }
        let degreesToRadians: (CGFloat) -> CGFloat = {
            return $0 / 180.0 * CGFloat(M_PI);
        }

        // calculate the size of the rotated view's containing box for our drawing space
        let rotatedViewBox = UIView(frame: CGRect(origin: CGPointZero, size: size));
        let t = CGAffineTransformMakeRotation(degreesToRadians(degrees));
        rotatedViewBox.transform = t;
        let rotatedSize = rotatedViewBox.frame.size

        // Create the bitmap context
        UIGraphicsBeginImageContext(rotatedSize);
        let bitmap = UIGraphicsGetCurrentContext();

        // Move the origin to the middle of the image so we will rotate and scale around the center.
        CGContextTranslateCTM(bitmap, rotatedSize.width / 2.0, rotatedSize.height / 2.0);

        // Rotate the image context
        CGContextRotateCTM(bitmap, degreesToRadians(degrees));

        // Now, draw the rotated/scaled image into the context
        var yFlip: CGFloat;

        if(flip){
            yFlip = CGFloat(-1.0);
        } else {
            yFlip = CGFloat(1.0);
        }

        CGContextScaleCTM(bitmap, yFlip, -1.0);
        CGContextDrawImage(bitmap, CGRectMake(-size.width / 2, -size.height / 2, size.width, size.height), CGImage);

        let newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();

        return newImage;
    }
}

这就是我调用扩展方法并将返回的图像设置为图像视图的方式。图像视图的 'contentMode' 属性设置为 'Scale to Fill'

currentPagePreviewImageVew.image = currentPagePreviewImageVew.image!.imageRotatedByDegrees(90, flip: false);

这是按下旋转按钮之前的样子

这是在按下旋转按钮一次之后。(看到图像没有旋转但它的大小已经改变)

这是当图像旋转 90 度时。(在图像旋转之后,但您可以看到其他视图在图像处于 0 度和 180 度时被拉伸,如上面的屏幕(2))

谁能告诉我我的代码有什么问题,如果有更好的解决方案,请告诉我。任何帮助将不胜感激。

已编辑: 拉伸视图是由于约束问题。我通过在图像视图上方的工具栏上设置高度约束来解决它。但仍然找不到第一次的答案。

【问题讨论】:

  • 我遇到了一个问题,因为更改仿射变换矩阵会影响自动布局约束,这可能是一个类似的问题
  • @simpleBob 你做了什么来完成你的工作?
  • 我在对象上删除并再次设置约束
  • @simpleBob 谢谢伙计。我会试试的。
  • @simpleBob 是的,这是一个约束问题。但仍然有第一次的事情。谢谢

标签: ios swift rotation uiimage swift-extensions


【解决方案1】:
    func flipImageVertical(originalImage: UIImage) -> UIImage
    {
        let tempImageView:UIImageView = UIImageView(image: originalImage)
        UIGraphicsBeginImageContext(tempImageView.frame.size)
        let context:CGContextRef = UIGraphicsGetCurrentContext()!
        let flipVertical:CGAffineTransform = CGAffineTransformMake(1,0,0,-1,0,tempImageView.frame.size.height)
        CGContextConcatCTM(context, flipVertical)
        tempImageView.layer .renderInContext(context)

        let flippedImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return flippedImage
    }

    func flipImageHorizontal(originalImage: UIImage) -> UIImage
    {
        let tempImageView:UIImageView = UIImageView(image: originalImage)
        UIGraphicsBeginImageContext(tempImageView.frame.size)
        let context:CGContextRef = UIGraphicsGetCurrentContext()!
        let flipHorizontal:CGAffineTransform = CGAffineTransformMake(-1,0,0,1,tempImageView.frame.size.width,0)

        CGContextConcatCTM(context, flipHorizontal)
        tempImageView.layer .renderInContext(context)

        let flippedImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return flippedImage
    }

【讨论】:

  • 这两种方法都运行良好。但这不是我想要的。我想旋转图像。不翻转
【解决方案2】:

你必须试试这个:

extension UIImage {
    public func imageRotatedByDegrees(degrees: Double, flip: Bool) -> UIImage {

        // calculate the size of the rotated view's containing box for our drawing space
        let rotatedViewBox = UIView(frame: CGRect(origin: CGPointZero, size: size))
        let t = CGAffineTransformMakeRotation(CGFloat(toRadian(degrees)))
        rotatedViewBox.transform = t
        let rotatedSize = rotatedViewBox.frame.size

        // Create the bitmap context
        UIGraphicsBeginImageContext(rotatedSize)
        let bitmap = UIGraphicsGetCurrentContext()

        CGContextSetAllowsAntialiasing(bitmap, true)
        CGContextSetShouldAntialias(bitmap, true)
        CGContextSetInterpolationQuality(bitmap, CGInterpolationQuality.High)

        // Move the origin to the middle of the image so we will rotate and scale around the center.
        CGContextTranslateCTM(bitmap, rotatedSize.width / 2.0, rotatedSize.height / 2.0)

        //   // Rotate the image context
        CGContextRotateCTM(bitmap, CGFloat(toRadian(degrees)))

        // Now, draw the rotated/scaled image into the context
        var yFlip: CGFloat

        if(flip){
            yFlip = CGFloat(-1.0)
        } else {
            yFlip = CGFloat(1.0)
        }

        CGContextScaleCTM(bitmap, yFlip, -1.0)
        CGContextDrawImage(bitmap, CGRectMake(-size.width / 2, -size.height / 2, size.width, size.height), CGImage)

        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return newImage
    }

然后用这个方法来满足你的新尺寸:

extension UIImage {
    public func resizeImage(newSize:CGSize) -> UIImage {

        let newRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, newSize.height))
        let imageRef:CGImageRef = self.CGImage!

        UIGraphicsBeginImageContextWithOptions(newSize, false, 0)
        let context:CGContextRef = UIGraphicsGetCurrentContext()!

        // Set the quality level to use when rescaling
        CGContextSetInterpolationQuality(context, CGInterpolationQuality.High)
        CGContextSetAllowsAntialiasing(context, true)
        CGContextSetShouldAntialias(context, true)

        let flipVertical:CGAffineTransform = CGAffineTransformMake(1, 0, 0, -1, 0, newSize.height)

        CGContextConcatCTM(context, flipVertical)
        // Draw into the context; this scales the image
        CGContextDrawImage(context, newRect, imageRef)

        // Get the resized image from the context and a UIImage
        let newImage:UIImage = UIImage(CGImage: CGBitmapContextCreateImage(context)!)

        UIGraphicsEndImageContext();
        return newImage
    }
}

【讨论】:

  • 感谢兄弟的帮助。但这并没有解决我的问题。
【解决方案3】:

我使用了下面的扩展,它工作正常。这实际上是 swift 3

import UIKit

extension UIImage {

    public func rotateImageByDegrees(_ degrees: CGFloat) -> UIImage {

        let degreesToRadians: (CGFloat) -> CGFloat = {
            return $0 / 180.0 * CGFloat(M_PI)
        }

        // calculate the size of the rotated view's containing box for our drawing space
        let rotatedViewBox = UIView(frame: CGRect(origin: CGPoint.zero, size: self.size))
        let t = CGAffineTransform(rotationAngle: degreesToRadians(degrees));
        rotatedViewBox.transform = t
        let rotatedSize = rotatedViewBox.frame.size

        // Create the bitmap context
        UIGraphicsBeginImageContext(rotatedSize)
        let bitmap = 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.0, y: rotatedSize.height / 2.0);

        // Rotate the image context
        bitmap?.rotate(by: degreesToRadians(degrees));

        // Now, draw the rotated/scaled image into the context
        bitmap?.scaleBy(x: 1.0, y: -1.0)
        bitmap?.draw(self.cgImage!, in: CGRect(x: -self.size.width / 2, y: -self.size.height / 2, width: self.size.width, height: self.size.height))

        let cgimage:CGImage  = bitmap!.makeImage()!
        return UIImage(cgImage: cgimage)
    }
}

所有其他事情都与问题中的相同。

【讨论】:

  • 感谢更新。我之前尝试过类似的方法,但对此没有帮助并且相同。看起来当我尝试旋转风景照片时它可以正常工作(即使我将照片旋转为纵向而不是再次旋转到横向)但是如果我将照片作为纵向而不是尝试旋转 - >第一次旋转使图像变形,另一个旋转工作正常,但会随着变形的照片旋转。
  • 我有 uiimageview 比我怎么用它。?
  • @MRizwan3395:你的意思是你想旋转 UIImageView?不是图像数据?如果你在旋转 UIImageView 时遇到这样的问题,那肯定是约束问题。
猜你喜欢
  • 1970-01-01
  • 2015-05-12
  • 2018-09-14
  • 1970-01-01
  • 2021-08-04
  • 1970-01-01
  • 2017-07-09
  • 2019-11-15
  • 1970-01-01
相关资源
最近更新 更多