【问题标题】:UIImageView: get transformed UIImageUIImageView:获取转换后的 UIImage
【发布时间】:2013-10-13 17:34:28
【问题描述】:

我正在使用这个旋转 UIImageView:

[UIView beginAnimations:nil context:nil];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
myImgView.transform = CGAffineTransformMakeRotation(angle*M_PI/180);
[UIView commitAnimations];

现在我想获得旋转的图像。我可以这样做吗?我试图使用来自this question 接受答案的 CGImageRotatedByAngle 函数使用 CoreGraphics 来制作它,但它转换的坐标有点不正确(最后我们得到第三个屏幕截图标记为错误)。如您所见,图像失去了原始大小并被裁剪。我的目标是获得像中心镜头一样的原始尺寸并旋转指定角度的图像。我的意思是要求旋转形状的大小保持不变,但新图像当然会大于初始图像。

【问题讨论】:

    标签: ios uiimageview core-graphics transform


    【解决方案1】:

    这是 heximal 答案的 swift 4.1 版本。

    extension CGImage {
    
        func rotated(by angle: CGFloat) -> CGImage? {
            let angleInRadians = angle * .pi / 180
    
            let imgRect = CGRect(x: 0, y: 0, width: width, height: height)
            let transform = CGAffineTransform.identity.rotated(by: angleInRadians)
            let rotatedRect = imgRect.applying(transform)
            let colorSpace = CGColorSpaceCreateDeviceRGB()
    
            guard let bmContext = CGContext(
                data: nil,
                width: Int(rotatedRect.size.width),
                height: Int(rotatedRect.size.height),
                bitsPerComponent: 8,
                bytesPerRow: 0,
                space: colorSpace,
                bitmapInfo: CGImageAlphaInfo.premultipliedFirst.rawValue)
                else {
                    return nil
            }
    
            bmContext.setAllowsAntialiasing(true)
            bmContext.setShouldAntialias(true)
            bmContext.interpolationQuality = .high
            bmContext.translateBy(x: rotatedRect.size.width * 0.5, y: rotatedRect.size.height * 0.5)
            bmContext.rotate(by: angleInRadians)
            let drawRect = CGRect(
                origin: CGPoint(x: -imgRect.size.width * 0.5, y: -imgRect.size.height * 0.5),
                size: imgRect.size)
            bmContext.draw(self, in: drawRect)
    
            guard let rotatedImage = bmContext.makeImage() else { return nil }
    
            return rotatedImage
        }
    
    }
    

    【讨论】:

      【解决方案2】:

      好的,我再次回答我自己的问题,希望它对将来的某些人有用...... 回到 CGImageRotatedByAngle,正如我之前所说,它提供了几乎所需的效果,但必须稍微改变坐标系平移序列。这是我得到预期结果的方式:

      - (CGImageRef)CGImageRotatedByAngle:(CGImageRef)imgRef angle:(CGFloat)angle {
      
          CGFloat angleInRadians = angle * (M_PI / 180);
          CGFloat width = CGImageGetWidth(imgRef);
          CGFloat height = CGImageGetHeight(imgRef);
      
          CGRect imgRect = CGRectMake(0, 0, width, height);
          CGAffineTransform transform = CGAffineTransformMakeRotation(angleInRadians);
          CGRect rotatedRect = CGRectApplyAffineTransform(imgRect, transform);
          CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
      
          CGContextRef bmContext = CGBitmapContextCreate(NULL,
                                                         rotatedRect.size.width,
                                                         rotatedRect.size.height,
                                                         8,
                                                         0,
                                                         colorSpace,
                                                         kCGImageAlphaPremultipliedFirst);
          CGContextSetAllowsAntialiasing(bmContext, YES);
          CGContextSetShouldAntialias(bmContext, YES);
          CGContextSetInterpolationQuality(bmContext, kCGInterpolationHigh);
          CGColorSpaceRelease(colorSpace);
          CGContextTranslateCTM( bmContext, 0.5f * rotatedRect.size.width, 0.5f * rotatedRect.size.height ) ;
          CGContextRotateCTM(bmContext, angleInRadians);
          CGContextDrawImage(bmContext, CGRectMake(-imgRect.size.width* 0.5f, -imgRect.size.height * 0.5f,
                                                   imgRect.size.width,
                                                   imgRect.size.height),
                             imgRef);
          CGImageRef rotatedImage = CGBitmapContextCreateImage(bmContext);
          CFRelease(bmContext);
          [(id)rotatedImage autorelease];
      
          return rotatedImage;
      }
      

      【讨论】:

      • 不要因为回答自己的问题而感到难过。如果它提供了对问题的准确、相关的答案,请随意继续并接受答案。见this wiki post
      【解决方案3】:

      它对我有用,另一种解决方法

      - (UIImage *)imageRotatedByDegrees:(CGFloat)degrees
      {
          CGRect imgRect = CGRectMake(0, 0, self.size.width, self.size.height);
          CGAffineTransform transform = CGAffineTransformMakeRotation(DegreesToRadians(degrees));
          CGRect rotatedRect = CGRectApplyAffineTransform(imgRect, transform);
          CGSize rotatedSize = rotatedRect.size;
      
          // Create the bitmap context
          UIGraphicsBeginImageContext(rotatedRect.size);
          CGContextRef 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, rotatedSize.height/2);
      
          // Rotate the image context
          CGContextRotateCTM(bitmap, DegreesToRadians(degrees));
      
          // Now, draw the rotated/scaled image into the context
          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;
      }
      

      【讨论】:

        猜你喜欢
        • 2012-07-03
        • 2012-07-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-16
        相关资源
        最近更新 更多