开发者

Rotate image and save the image with the Rotated state

开发者 https://www.devze.com 2023-03-19 00:43 出处:网络
I want to rotate a image with UIslider control. I have done that with the below function - (void)rotateImage:(UIImageView *)image duration:(NSTimeInterval)duration

I want to rotate a image with UIslider control.

I have done that with the below function

- (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];}

by using this function it will work perfect but the problem is that i can not save the image refere开发者_运维知识库nce that is rotated. i have to use that rotated image for further processing.

So how can i save the image that is in Rotated position?

please Help me over this issue

Thanks


i found the solution of my question

use This below method for This

- (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;
}

call this method with

 UIImage  *rotated2 = [self upsideDownBunny:rotation];

where rotation is sliderValue between 0 to 360.

now we can save the rotated state.


I tried the code above, it's working but only for a SQUARE image, here is another working solution, which will redraw the image and keep the right width/height :

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

}

The rotation parameter here is to give in Radian. You can perform the conversion by adding this above your function (or in you .m file directly)

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

Finally, I called this with an animation :

  [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)];
}];

I hope this could help too !

Cheers.


One approach to further processing is applying more transformation in sequence, like in:

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

in this case you would apply a scaling to your rotated image.

If you need saving this information in order to be able to redo the transformation at some later point, you can simply store the angle of the rotation, the scaling factor (in my example), and the build the transform once again.

You could also think of storing your CGAffineTransform in a ivar of your class or other mechanism.

EDIT:

if by saving you mean save to a file, you can convert your view to an image with this code:

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

then you save the NSData to file

For PNG:

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


You can render your rotated image into another image:

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

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

and then get the PNG data from that and save it to a file

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

Proviso, I typed this into StackOverflow, not a compiler :-)


Save the transform value of your UIImageView and apply this transform value next time when you want to use this UIImageView or even in anoother UIImageView .

0

精彩评论

暂无评论...
验证码 换一张
取 消