首页 文章

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

提问于
浏览
1

我想用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 回答

  • 2

    我找到了问题的解决方案

    使用以下方法

    - (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 .

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

  • 0

    我尝试了上面的代码,它正在工作,但仅适用于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)];
    }];
    

    我希望这也有帮助!

    干杯 .

  • 3

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

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

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

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

    您还可以考虑将 CGAffineTransform 存储在您的 class 或其他机制的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];
    
  • 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,而不是编译器:-)

  • 0

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

相关问题