6

我有一个包含图像的 UIImageView。此时,用户可以单击将 UIImageView 中的图像保存到磁盘。

我想这样做,以便用户可以单击以旋转 UIImageView 并在视图中旋转 UImage,以便在保存图像时保持新的旋转。

此刻我有

- (IBAction)rotateImage:(id)sender {

float degrees = 90; //the value in degrees
self.imagePreview.transform = CGAffineTransformMakeRotation(degrees * M_PI/180);

}

有人可以指出我保持当前旋转的正确方向吗?

谢谢

4

6 回答 6

12

我的旧应用程序中有这样的代码。但是此代码可以简化,因为您无需将其旋转到非 90 度角。

Objective-C

@implementation UIImage (Rotation)

- (UIImage *)imageRotatedOnDegrees:(CGFloat)degrees
{
  // Follow ing code can only rotate images on 90, 180, 270.. degrees.
  CGFloat roundedDegrees = (CGFloat)(round(degrees / 90.0) * 90.0);
  BOOL sameOrientationType = ((NSInteger)roundedDegrees) % 180 == 0;
  CGFloat radians = M_PI * roundedDegrees / 180.0;
  CGSize newSize = sameOrientationType ? self.size : CGSizeMake(self.size.height, self.size.width);

  UIGraphicsBeginImageContext(newSize);
  CGContextRef ctx = UIGraphicsGetCurrentContext();
  CGImageRef cgImage = self.CGImage;
  if (ctx == NULL || cgImage == NULL) {
    UIGraphicsEndImageContext();
    return self;
  }

  CGContextTranslateCTM(ctx, newSize.width / 2.0, newSize.height / 2.0);
  CGContextRotateCTM(ctx, radians);
  CGContextScaleCTM(ctx, 1, -1);
  CGPoint origin = CGPointMake(-(self.size.width / 2.0), -(self.size.height / 2.0));
  CGRect rect = CGRectZero;
  rect.origin = origin;
  rect.size = self.size;
  CGContextDrawImage(ctx, rect, cgImage);
  UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();
  return image ?: self;
}

@end

迅速

extension UIImage {

  func imageRotated(on degrees: CGFloat) -> UIImage {
    // Following code can only rotate images on 90, 180, 270.. degrees.
    let degrees = round(degrees / 90) * 90
    let sameOrientationType = Int(degrees) % 180 == 0
    let radians = CGFloat.pi * degrees / CGFloat(180)
    let newSize = sameOrientationType ? size : CGSize(width: size.height, height: size.width)

    UIGraphicsBeginImageContext(newSize)
    defer {
      UIGraphicsEndImageContext()
    }

    guard let ctx = UIGraphicsGetCurrentContext(), let cgImage = cgImage else {
      return self
    }

    ctx.translateBy(x: newSize.width / 2, y: newSize.height / 2)
    ctx.rotate(by: radians)
    ctx.scaleBy(x: 1, y: -1)
    let origin = CGPoint(x: -(size.width / 2), y: -(size.height / 2))
    let rect = CGRect(origin: origin, size: size)
    ctx.draw(cgImage, in: rect)
    let image = UIGraphicsGetImageFromCurrentImageContext()
    return image ?? self
  }

}
于 2013-07-28T14:46:32.813 回答
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;
}
于 2015-04-23T14:56:28.420 回答
3

在斯威夫特 4

imageView.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi/2))

于 2019-01-29T06:51:58.533 回答
1

UIButton 的突出显示状态没有采用正常插入的旋转图像的正确方向。所以我不得不像@RyanG 显示的那样重新绘制图像。这是 Swift 2.2 代码:

extension UIImage
{
    /// Rotate an image by any given radians.
    /// Works for 2x and 3x retina as well.
    func imageRotatedByDegrees(degrees: Double) -> UIImage
    {
        let radians = CGFloat(degrees * (M_PI / 180.0))

        let rotatedViewBox = UIView(frame: CGRect(origin: CGPointZero, size: self.size))
        let t: CGAffineTransform = CGAffineTransformMakeRotation(radians)
        rotatedViewBox.transform = t
        let rotatedSize = rotatedViewBox.frame.size

        UIGraphicsBeginImageContextWithOptions(rotatedSize, false, self.scale)
        let bitmap = UIGraphicsGetCurrentContext()

        CGContextTranslateCTM(bitmap, rotatedSize.width / 2, rotatedSize.height / 2)
        CGContextRotateCTM(bitmap, radians)
        CGContextScaleCTM(bitmap, 1.0, -1.0)
        CGContextDrawImage(bitmap, CGRect(origin: CGPoint(x: -self.size.width / 2, y: -self.size.height / 2), size: self.size), self.CGImage)

        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage
    }
}
于 2016-06-17T16:09:12.767 回答
0

由@RyanG 的回答制作的 Swift 版本,并进行了一些修复:

func rotated(by degrees: CGFloat) -> UIImage {
    let radians : CGFloat = degrees * CGFloat(.pi / 180.0)
    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
    UIGraphicsBeginImageContextWithOptions(rotatedSize, false, self.scale)
    defer { UIGraphicsEndImageContext() }
    guard let bitmap = UIGraphicsGetCurrentContext(), let cgImage = self.cgImage else {
      return self
    }
    bitmap.translateBy(x: rotatedSize.width / 2, y: rotatedSize.height / 2)
    bitmap.rotate(by: radians)
    bitmap.scaleBy(x: 1.0, y: -1.0)
    bitmap.draw(cgImage, in: CGRect(x: -self.size.width / 2, y: -self.size.height / 2, width: self.size.width, height: self.size.height))
    guard let newImage = UIGraphicsGetImageFromCurrentImageContext() else {
      return self
    }
    return newImage
  }
于 2018-12-20T22:47:11.590 回答
-1

self.imageview.transform = CGAffineTransformMakeRotation(M_PI/2);

于 2013-07-28T14:37:02.197 回答