旋转图像并以旋转状态保存图像

时间:2011-07-07 08:45:54

标签: objective-c image rotation

我想用UIslider控件旋转图像。

我已经使用以下功能

完成了这项工作

- (void)rotateImage:(UIImageView *)image duration:(NSTimeInterval)duration 
              curve:(int)curve degrees:(CGFloat)degrees
{
    // Setup the animation
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:duration];
    [UIView setAnimationCurve:curve];
    [UIView setAnimationBeginsFromCurrentState:YES];

// The transform matrix CGAffineTransform transform = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(degrees)); image.transform = transform; // Commit the changes [UIView commitAnimations];}

通过使用此功能,它将完美 但问题是我无法保存旋转的图像参考。 我必须使用旋转的图像进行进一步处理。

那么如何保存处于旋转位置的图像?

请帮我解决这个问题

由于

5 个答案:

答案 0 :(得分:3)

我找到了我的问题的解决方案

使用以下方法进行此

- (UIImage*)upsideDownBunny:(CGFloat)radians withImage:(UIImage*)testImage {
    __block CGImageRef cgImg;
    __block CGSize imgSize;
    __block UIImageOrientation orientation;
    dispatch_block_t createStartImgBlock = ^(void) {
        // UIImages should only be accessed from the main thread

        UIImage *img =testImage
        imgSize = [img size]; // this size will be pre rotated
        orientation = [img imageOrientation];
        cgImg = CGImageRetain([img CGImage]); // this data is not rotated
    };
    if([NSThread isMainThread]) {
        createStartImgBlock();
    } else {
        dispatch_sync(dispatch_get_main_queue(), createStartImgBlock);
    }
    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
    // in iOS4+ you can let the context allocate memory by passing NULL
    CGContextRef context = CGBitmapContextCreate( NULL,
                                                 imgSize.width,
                                                 imgSize.height,
                                                 8,
                                                 imgSize.width * 4,
                                                 colorspace,
                                                 kCGImageAlphaPremultipliedLast);
    // rotate so the image respects the original UIImage's orientation
    switch (orientation) {
        case UIImageOrientationDown:
            CGContextTranslateCTM(context, imgSize.width, imgSize.height);
            CGContextRotateCTM(context, -radians);
            break;
        case UIImageOrientationLeft:
            CGContextTranslateCTM(context, 0.0, imgSize.height);
            CGContextRotateCTM(context, 3.0 * -radians / 2.0);
            break;
        case UIImageOrientationRight:
            CGContextTranslateCTM(context,imgSize.width, 0.0);
            CGContextRotateCTM(context, -radians / 2.0);
            break;
        default:
            // there are mirrored modes possible
            // but they aren't generated by the iPhone's camera
            break;
    }
    // rotate the image upside down

    CGContextTranslateCTM(context, +(imgSize.width * 0.5f), +(imgSize.height * 0.5f));
    CGContextRotateCTM(context, -radians);
    //CGContextDrawImage( context, CGRectMake(0.0, 0.0, imgSize.width, imgSize.height), cgImg );
    CGContextDrawImage(context, (CGRect){.origin.x = -imgSize.width* 0.5f , .origin.y = -imgSize.width* 0.5f , .size.width = imgSize.width, .size.height = imgSize.width}, cgImg);
    // grab the new rotated image
    CGContextFlush(context);
    CGImageRef newCgImg = CGBitmapContextCreateImage(context);
    __block UIImage *newImage;
    dispatch_block_t createRotatedImgBlock = ^(void) {
        // UIImages should only be accessed from the main thread
        newImage = [UIImage imageWithCGImage:newCgImg];
    };
    if([NSThread isMainThread]) {
        createRotatedImgBlock();
    } else {
        dispatch_sync(dispatch_get_main_queue(), createRotatedImgBlock);
    }
    CGColorSpaceRelease(colorspace);
    CGImageRelease(newCgImg);
    CGContextRelease(context);
    return newImage;
}

使用

调用此方法
 UIImage  *rotated2 = [self upsideDownBunny:rotation];

其中rotation是0到360之间的sliderValue。

现在我们可以保存旋转状态。

答案 1 :(得分:2)

我尝试了上面的代码,它只能用于SQUARE图像,这是另一个有效的解决方案,它将重绘图像并保持正确的宽度/高度:

- (UIImage *) rotatedImage:(UIImage *)imageRotation and:(CGFloat) rotation
{
// Calculate Destination Size
CGAffineTransform t = CGAffineTransformMakeRotation(rotation);
CGRect sizeRect = (CGRect) {.size = imageRotation.size};
CGRect destRect = CGRectApplyAffineTransform(sizeRect, t);
CGSize destinationSize = destRect.size;

// Draw image
UIGraphicsBeginImageContext(destinationSize);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, destinationSize.width / 2.0f, destinationSize.height / 2.0f);
CGContextRotateCTM(context, rotation);
[imageRotation drawInRect:CGRectMake(-imageRotation.size.width / 2.0f, -imageRotation.size.height / 2.0f, imageRotation.size.width, imageRotation.size.height)];

// Save image
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;

}

这里的旋转参数是Radian。您可以通过在函数上方(或直接在.m文件中)添加此项来执行转换

#define M_PI   3.14159265358979323846264338327950288   /* pi */
#define DEGREES_TO_RADIANS(angle) (angle / 180.0 * M_PI)

最后,我用动画调用了它:

  [UIView animateWithDuration:0.5f delay:0 options:UIViewAnimationCurveEaseIn animations:^{
    //Only used for the ANIMATION of the uiimage
    imageView.transform = CGAffineTransformRotate(editorPad.transform, DEGREES_TO_RADIANS(90));
}completion:^(BOOL finished) {
    // Workaround : Need to set previous transformation back or the next step will turn the image more
    imageView.transform = CGAffineTransformRotate(imageView.transform, DEGREES_TO_RADIANS(-90));
    imageView.image = [self imageView.image and:DEGREES_TO_RADIANS(90)];
}];

我希望这也有帮助!

干杯。

答案 2 :(得分:0)

进一步处理的一种方法是按顺序应用更多转换,如:

CGAffineTransform transform = CGAffineTransformScale(previousTransform, newScale, newScale);

在这种情况下,您可以对旋转的图像应用缩放。

如果您需要保存此信息以便能够在稍后的某个时间点重做转换,则可以简单地存储旋转角度,缩放系数(在我的示例中)以及再次构建转换。

您还可以考虑将CGAffineTransform存储在班级或其他机制的ivar中。

编辑:

如果通过保存意味着保存到文件,您可以使用以下代码将视图转换为图像:

NSData *data;
NSBitmapImageRep *rep;
rep = [self bitmapImageRepForCachingDisplayInRect:[self frame]];
[self cacheDisplayInRect:[self frame] toBitmapImageRep:rep];
data = [rep TIFFRepresentation];

然后将NSData保存到文件

对于PNG:

 UIGraphicsBeginImageContext(self.bounds.size);
 [self.layer renderInContext:UIGraphicsGetCurrentContext()];
 UIImage* image1 = UIGraphicsGetImageFromCurrentImageContext();
 UIGraphicsEndImageContext();
 NSData *imageData = UIImagePNGRepresentation(image1);
 [imageData writeToFile:filePath atomically:YES];

答案 3 :(得分:0)

您可以将旋转的图像渲染到另一张图像中:

UIGraphicsBeginImageContext(aCGRectToHoldYourImage);
CALayer* layer = myRotatedImageView.layer;

[layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

然后从中获取PNG数据并将其保存到文件

NSData* myPNGData = [viewImage UIImagePNGRepresentation];
[myPNGData writeToFile:@"aFileName.png" atomically:YES];

Proviso,我在StackOverflow中输入了这个,而不是编译器: - )

答案 4 :(得分:0)

保存UIImageView的变换值,并在下次要使用此UIImageView或甚至在另一个UIImageView中时应用此变换值。