Повернуть изображение и сохранить изображение в повернутом состоянии - PullRequest
1 голос
/ 07 июля 2011

Я хочу повернуть изображение с помощью элемента управления 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];</p>

<code>// The transform matrix
CGAffineTransform transform = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(degrees));
image.transform = transform;

// Commit the changes
[UIView commitAnimations];}
</code>

, используя эту функциюбудет работать отлично, но проблема в том, что я не могу сохранить ссылку на изображение, которое вращается.Мне нужно использовать это повернутое изображение для дальнейшей обработки.

Итак, как мне сохранить изображение, находящееся в повернутой позиции?

Пожалуйста, помогите мне решить эту проблему

Спасибо

Ответы [ 5 ]

3 голосов
/ 18 июля 2011

я нашел решение моего вопроса

используйте этот метод ниже для этого

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

, где вращение - значение слайдера от 0 до 360.

теперь мы можем сохранить повернутое состояние.

2 голосов
/ 30 июля 2014

Я попробовал код выше, он работает, но только для КВАДРАТНОГО изображения, вот другое рабочее решение, которое перерисовает изображение и сохранит правильную ширину / высоту:

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

}

Параметр вращения здесь дан в радианах.Вы можете выполнить преобразование, добавив это выше вашей функции (или непосредственно в ваш файл .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)];
}];

Я надеюсь, что этотоже может помочь!

Приветствия.

0 голосов
/ 23 мая 2012

Сохраните значение преобразования вашего UIImageView и примените это значение преобразования в следующий раз, когда вы захотите использовать этот UIImageView или даже в другом UIImageView.

0 голосов
/ 07 июля 2011

Вы можете визуализировать ваше повернутое изображение в другое изображение:

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 голосов
/ 07 июля 2011

Один из подходов к дальнейшей обработке заключается в применении большего количества последовательных преобразований, например:

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

, в этом случае вы примените масштабирование к повернутому изображению.

Если вам нужно сохранитьЭта информация, чтобы иметь возможность повторить преобразование в более поздний момент, вы можете просто сохранить угол поворота, коэффициент масштабирования (в моем примере) и построить преобразование еще раз.

Выможет также подумать о сохранении вашего CGAffineTransform в иваре вашего класса или другого механизма.

РЕДАКТИРОВАТЬ:

, если под сохранением вы имеете в виду сохранение в файл, вы можете преобразовать свое представление визображение с этим кодом:

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];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...