【问题标题】:How to rotate UIImage如何旋转 UIImage
【发布时间】:2013-01-29 05:53:41
【问题描述】:

我正在为 iPad 开发一个 iOS 应用程序。有没有办法将 UIImage 旋转 90º,然后将其添加到 UIImageView?我尝试了很多不同的代码,但都没有奏效......

谢谢!

【问题讨论】:

    标签: objective-c ipad ios6 uiimageview uiimage


    【解决方案1】:

    这是 @RyanG 的 Objective C 代码的 swift 版本,作为 UIImage 的扩展:

    extension UIImage {
    
        func rotate(byDegrees degree: Double) -> UIImage {
            let radians = CGFloat(degree*M_PI)/180.0 as CGFloat
            let rotatedViewBox = UIView(frame: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height))
            let t = CGAffineTransform(rotationAngle: radians)
            rotatedViewBox.transform = t
            let rotatedSize = rotatedViewBox.frame.size
            let scale = UIScreen.main.scale
            UIGraphicsBeginImageContextWithOptions(rotatedSize, false, scale)
            let bitmap = UIGraphicsGetCurrentContext()
            CGContextTranslateCTM(bitmap, rotatedSize.width / 2, rotatedSize.height / 2);
    
            bitmap!.rotate(by: radians);
    
            bitmap!.scaleBy(x: 1.0, y: -1.0);
            CGContextDrawImage(bitmap, CGRectMake(-self.size.width / 2, -self.size.height / 2 , self.size.width, self.size.height), self.CGImage );
    
            let newImage = UIGraphicsGetImageFromCurrentImageContext()
    
            return newImage
        }
    
    }
    

    用法是image.rotate(degree)

    【讨论】:

      【解决方案2】:

      当我想改变图像的方向(顺时针旋转 90 度)时,这就是我所做的。

      //Checking for the orientation ie, image taken from camera is in portrait or not.
      if(yourImage.imageOrientation==3)
      {
          //Image is in portrait mode.
          yourImage=[self imageToRotate:yourImage RotatedByDegrees:90.0];
      }
      
      - (UIImage *)image:(UIImage *)imageToRotate RotatedByDegrees:(CGFloat)degrees
      {
          CGFloat radians = degrees * (M_PI / 180.0);
      
          UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0,0, image.size.height, image.size.width)];
          CGAffineTransform t = CGAffineTransformMakeRotation(radians);
          rotatedViewBox.transform = t;
          CGSize rotatedSize = rotatedViewBox.frame.size;
      
          UIGraphicsBeginImageContextWithOptions(rotatedSize, NO, [[UIScreen mainScreen] scale]);
          CGContextRef bitmap = UIGraphicsGetCurrentContext();
      
          CGContextTranslateCTM(bitmap, rotatedSize.height / 2, rotatedSize.width / 2);
      
          CGContextRotateCTM(bitmap, radians);
      
          CGContextScaleCTM(bitmap, 1.0, -1.0);
          CGContextDrawImage(bitmap, CGRectMake(-image.size.width / 2, -image.size.height / 2 , image.size.height, image.size.width), image.CGImage );
          UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
          UIGraphicsEndImageContext();
      
          return newImage;
      }
      

      旋转后的图像大小可能 >= 15MB(根据我的经验)。所以你应该压缩它并使用它。否则,您可能会遇到导致内存压力的崩溃。下面给出了我用于压缩的代码。

      NSData *imageData = UIImageJPEGRepresentation(yourImage, 1);
      //1 - it represents the quality of the image.
      NSLog(@"Size of Image(bytes):%d",[imageData length]);
      //Here I used a loop because my requirement was, the image size should be <= 4MB.
      //So put an iteration for more than 1 time upto when the image size is gets <= 4MB.
      for(int loop=0;loop<100;loop++)
      {
          if([imageData length]>=4194304)  //4194304 = 4MB in bytes.
          {
              imageData=UIImageJPEGRepresentation(yourImage, 0.3);
              yourImage=[[UIImage alloc]initWithData:imageData];
          }
          else
          {
              NSLog(@"%d time(s) compressed.",loop);
              break;
          }
      }
      

      现在您的yourImage 可以在任何地方使用.. 编码愉快...

      【讨论】:

      • imageToRotate 未编译,您使用了错误的参数名称 image 而不是 imageToRotate 参数
      【解决方案3】:
      UIImage *img = [UIImage imageWithName@"aaa.png"];
      UIImage *image = [UIImage imageWithCGImage:img.CGImage scale:1.0 orientation:UIImageOrientationRight];
      

      【讨论】:

        【解决方案4】:

        感谢 Jason Crocker,这解决了我的问题。只进行了一次小的修正,两个位置的高度和宽度互换,不会发生变形,即,

        UIGraphicsBeginImageContext(CGSizeMake(size.width, size.height));
        [[UIImage imageWithCGImage:[sourceImage CGImage] scale:1.0 orientation:clockwise ? UIImageOrientationRight : UIImageOrientationLeft]  drawInRect:CGRectMake(0,0,size.width,size.height)]; 
        

        CGContextRotateCTM 无法解决我的问题,我不知道为什么。我的问题是我正在将我的图像传输到服务器并且它总是显示为 90 度。您可以通过将图像复制到您在 Mac 上运行的 MS Office 程序来轻松测试您的图像是否可以在非苹果世界中工作。

        【讨论】:

          【解决方案5】:

          这会将图像旋转任意给定的度数。

          请注意,这也适用于 2x 和 3x 视网膜

          - (UIImage *)imageRotatedByDegrees:(CGFloat)degrees {
              CGFloat radians = DegreesToRadians(degrees);
          
              UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.size.width, self.size.height)];
              CGAffineTransform t = CGAffineTransformMakeRotation(radians);
              rotatedViewBox.transform = t;
              CGSize rotatedSize = rotatedViewBox.frame.size;
          
              UIGraphicsBeginImageContextWithOptions(rotatedSize, NO, [[UIScreen mainScreen] scale]);
              CGContextRef bitmap = UIGraphicsGetCurrentContext();
          
              CGContextTranslateCTM(bitmap, rotatedSize.width / 2, rotatedSize.height / 2);
          
              CGContextRotateCTM(bitmap, radians);
          
              CGContextScaleCTM(bitmap, 1.0, -1.0);
              CGContextDrawImage(bitmap, CGRectMake(-self.size.width / 2, -self.size.height / 2 , self.size.width, self.size.height), self.CGImage );
          
              UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
              UIGraphicsEndImageContext();
          
              return newImage;
          }
          

          【讨论】:

          • 这很好,但是有没有一种无需创建 UIView 的方法呢?我的理解是 UIView 是一个相当重量级的对象。谢谢!
          • 我发现可以使用 CALayer 代替 UIView。创建图层后,您必须设置框架属性。您还必须将 CATransform3DMakeAffineTransform 函数应用于 CAAffineTransform 对象 ("t") 以在图层上设置变换属性。其他一切都按原样工作。我的理解是 CALayer 是一个更轻量级的对象。
          • UIView 必须在主线程上执行,所以最好避免它。我发现与这个不使用 UIView 的答案非常相似 - stackoverflow.com/a/20860719/2870783
          【解决方案6】:

          使用 Swift,您可以通过以下方式旋转图像:

          var image: UIImage = UIImage(named: "headerBack.png")
          var imageRotated: UIImage = UIImage(CGImage: image.CGImage, scale:1, orientation: UIImageOrientation.UpMirrored)
          

          【讨论】:

            【解决方案7】:

            如果你想旋转UIImage而不是UIImageView,还有imageWithCIImage:scale:orientation

            具有以下方向之一:

            typedef enum {
               UIImageOrientationUp,
               UIImageOrientationDown,   // 180 deg rotation
               UIImageOrientationLeft,   // 90 deg CW
               UIImageOrientationRight,   // 90 deg CCW
               UIImageOrientationUpMirrored,    // vertical flip
               UIImageOrientationDownMirrored,  // horizontal flip
               UIImageOrientationLeftMirrored,  // 90 deg CW then perform horizontal flip
               UIImageOrientationRightMirrored, // 90 deg CCW then perform vertical flip
            } UIImageOrientation;
            

            【讨论】:

              【解决方案8】:

              要旋转像素,您可以使用以下方法。这将创建一个带有旋转元数据的中间 UIImage,并将其渲染到一个宽度/高度尺寸转置的图像上下文中。生成的图像具有旋转的像素(即底层 CGImage)

              - (UIImage*)rotateUIImage:(UIImage*)sourceImage clockwise:(BOOL)clockwise
              {
                  CGSize size = sourceImage.size;
                  UIGraphicsBeginImageContext(CGSizeMake(size.height, size.width));
                  [[UIImage imageWithCGImage:[sourceImage CGImage] scale:1.0 orientation:clockwise ? UIImageOrientationRight : UIImageOrientationLeft] drawInRect:CGRectMake(0,0,size.height ,size.width)];
                  UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
                  UIGraphicsEndImageContext();
              
                  return newImage;
              }
              

              还有其他可能的值可以传递给方向参数以实现 180 度旋转和翻转等。

              【讨论】:

              • 如果原始图像是UIImageOrientationRight,而您在此处设置UIImageOrientationLeft,则生成的输出将被压缩以适应新尺寸。
              【解决方案9】:

              另一种方法是使用 Core Graphics 再次渲染 UIImage。

              获得上下文后,使用CGContextRotateCTM

              更多信息on this Apple Doc

              【讨论】:

                【解决方案10】:

                您可以旋转UIImageView 本身:

                UIImageView *iv = [[UIImageView alloc] initWithImage:image];
                iv.transform = CGAffineTransformMakeRotation(M_PI_2);
                

                或者如果你真的想改变图像,你可以使用this answer的代码,它可以工作。

                【讨论】:

                • 我按照它说的做,但我有一个问题......我从左上角旋转图像,我如何设置它从 UIImage 的中心旋转图像?
                • 你可以玩iv.layer.anchorPoint,但它的默认值是图层的中心,所以我不确定为什么它会从左上角旋转图像。
                • 否,但我使用了您提供给我的链接中的代码。所以它是CGContextRotateCTM
                • 我明白了。给你:stackoverflow.com/questions/5983090/…
                • 我试过了,但只适用于方形图片。其他图像失真...我该怎么办?
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2010-11-21
                • 2023-03-28
                • 1970-01-01
                • 1970-01-01
                • 2010-12-17
                • 2018-08-14
                相关资源
                最近更新 更多