Изображение, снятое с пользовательской камеры, поворачивается после кадрирования iOS

Я столкнулся с проблемой поворота изображения после обрезки изображения. Ниже я разместил пошаговые методы, которые я использовал в настоящее время.

Вот процедура, которой я следовал, чтобы получить результат:

Шаг 1. Сделайте снимок с помощью специальной камеры.

- (void)captureImageWithCompletionHander:(void (^)(id))completionHandler{
    [_cameraOverlayView hideHightLightOverlay];
    if (_isCapturing) return;

    __weak typeof(self) weakSelf = self;
    [weakSelf hideGLKView:YES completion:^{
        [weakSelf hideGLKView:NO completion:^{
            [weakSelf hideGLKView:YES completion:nil];
        }];
    }];
    _isCapturing = YES;

    AVCaptureConnection *videoConnection = nil;
    for (AVCaptureConnection *connection in self.stillImageOutput.connections){
        for (AVCaptureInputPort *port in [connection inputPorts]){
            if ([[port mediaType] isEqual:AVMediaTypeVideo] ){
                videoConnection = connection;
                break;
            }
        }
        if (videoConnection) break;
    }

    [self.stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error){
        if(!CMSampleBufferIsValid(imageSampleBuffer)){
            return;
        }
        NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];

        UIImage * capturedImage = [[UIImage alloc]initWithData:imageData scale:1];
        NSLog(@"%lu",(unsigned long)UIImageJPEGRepresentation(capturedImage, 1.0).length);
        if (_myDevice == [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo][0]) {
            capturedImage = capturedImage;
        }else if (_myDevice == [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo][1]) {
        }

        [weakSelf hideGLKView:NO completion:nil];
        completionHandler(capturedImage);
         _isCapturing = NO;
     }];
}

Шаг 2. Исправьте ориентацию

-(id)initWithImage:(UIImage*) image{
    self =  [super init];
    if (self){
        self.originalImage = [image fixOrientation];
    }

    return self;
}

//Method for fix orientation
@implementation UIImage (fixOrientation)

- (UIImage *)fixOrientation {

    // No-op if the orientation is already correct
    if (self.imageOrientation == UIImageOrientationUp) return self;

    // We need to calculate the proper transformation to make the image upright.
    // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
    CGAffineTransform transform = CGAffineTransformIdentity;

    switch (self.imageOrientation) {
        case UIImageOrientationDown:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;

        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
            transform = CGAffineTransformTranslate(transform, self.size.width, 0);
            transform = CGAffineTransformRotate(transform, M_PI_2);
            break;

        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, 0, self.size.height);
            transform = CGAffineTransformRotate(transform, -M_PI_2);
            break;
        case UIImageOrientationUp:
        case UIImageOrientationUpMirrored:
            break;
    }

    switch (self.imageOrientation) {
        case UIImageOrientationUpMirrored:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, self.size.width, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;

        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, self.size.height, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;
        case UIImageOrientationUp:
        case UIImageOrientationDown:
        case UIImageOrientationLeft:
        case UIImageOrientationRight:
            break;
    }

    // Now we draw the underlying CGImage into a new context, applying the transform
    // calculated above.
    CGContextRef ctx = CGBitmapContextCreate(NULL, self.size.width, self.size.height,
                                             CGImageGetBitsPerComponent(self.CGImage), 0,
                                             CGImageGetColorSpace(self.CGImage),
                                             CGImageGetBitmapInfo(self.CGImage));
    CGContextConcatCTM(ctx, transform);
    switch (self.imageOrientation) {
        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            // Grr...
            CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage);
            break;

        default:
            CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage);
            break;
    }

    // And now we just create a new UIImage from the drawing context
    CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
    UIImage *img = [UIImage imageWithCGImage:cgimg];
    CGContextRelease(ctx);
    CGImageRelease(cgimg);
    return img;
}
@end

Шаг 3. Обрезать изображение

-(UIImage *)cropImage:(UIImage *)image{
    CGFloat overlayHeight = self.frame.size.height;
    UIImageOrientation originalOrientation = image.imageOrientation;
    CGFloat originalScale = image.scale;
    CIImage *rawImage = [CIImage imageWithCGImage:image.CGImage];

    NSMutableDictionary *rectangleCoordinates = [NSMutableDictionary new];
    rectangleCoordinates[@"inputTopLeft"] = [CIVector vectorWithCGPoint:CGPointMake(topLeftPath.x * _absoluteWidth, (overlayHeight - topLeftPath.y) * _absoluteHeight)];
    rectangleCoordinates[@"inputTopRight"] = [CIVector vectorWithCGPoint:CGPointMake(topRightPath.x * _absoluteWidth, (overlayHeight - topRightPath.y) * _absoluteHeight)];
    rectangleCoordinates[@"inputBottomLeft"] = [CIVector vectorWithCGPoint:CGPointMake(bottomLeftPath.x * _absoluteWidth, (overlayHeight - bottomLeftPath.y) * _absoluteHeight)];
    rectangleCoordinates[@"inputBottomRight"] = [CIVector vectorWithCGPoint:CGPointMake(bottomRightPath.x * _absoluteWidth, (overlayHeight - bottomRightPath.y) * _absoluteHeight)];
    rawImage = [rawImage imageByApplyingFilter:@"CIPerspectiveCorrection" withInputParameters:rectangleCoordinates];

    CIContext *context = [CIContext contextWithOptions:nil];
    CGImageRef cgImage = [context createCGImage:rawImage fromRect:[rawImage extent]];
    UIImage *RImage = [UIImage imageWithCGImage:cgImage scale:originalScale orientation:originalOrientation];
    return RImage;
}

Результат:

  • После захвата изображения я показываю исходное изображение, и оно выглядит ровным. Без вопросов.

См. Изображение:  введите описание изображения здесь

  • Но после обрезки он поворачивается

См. Изображение:  введите описание изображения здесь

Некоторые ссылки, которые я уже пробовал, но не работал:

Использование CoreImage для фильтрации изображения приводит к поворот изображения

Ориентация изображения результата iOS UIImagePickerController после загрузки

iOS - UIImageView - как обрабатывать ориентацию изображения UIImage

Как получить Правильная ориентация изображения, выбранного из галереи изображений по умолчанию

Конвертируйте UIImage в CIImage для обрезки в CGRect. AVFoundation

Будет здорово, если кто-нибудь поможет решить эту проблему.

Заранее спасибо.


person Mayur    schedule 01.12.2016    source источник
comment
попробуйте это для кадрирования .. - (UIImage ) crop: (CGRect) rect {rect = CGRectMake (rect.origin.x self.scale, rect.origin.y self.scale, rect .size.width self.scale, rect.size.height * self.scale); CGImageRef imageRef = CGImageCreateWithImageInRect ([собственное изображение CGImage], прямоугольник); UIImage * результат = [UIImage imageWithCGImage: imageRef scale: self.scale Ориентация: self.imageOrientation]; CGImageRelease (imageRef); вернуть результат; }   -  person Himanshu Moradiya    schedule 01.12.2016
comment
Я думаю, вам следует сослаться на этот ответ для обрезки изображения. Я использую этот ответ в своем проекте и решаю свою проблему. stackoverflow.com / questions / 158914 / cropping-an-uiimage   -  person Himanshu Moradiya    schedule 01.12.2016
comment
stackoverflow.com/questions/5427656 / Перейти по ссылке выше   -  person arvind    schedule 01.12.2016


Ответы (2)


После стольких экспериментов и опробования стольких решений, наконец, я решил эту проблему, перейдя на UIBeizerPath.

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

Итак, попробовал с UIBeizerPath, и вот что я сделал:

UIBezierPath *path = [_overlayView getPath];
CGRect rect = CGRectZero;
rect.size = _detectedImage.frame.size;

CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.frame = CGRectMake(0, 0, _detectedImage.frame.size.width, _detectedImage.frame.size.height);
shapeLayer.path = path.CGPath;
shapeLayer.fillColor = [[UIColor whiteColor] CGColor];
shapeLayer.backgroundColor = [[UIColor clearColor] CGColor];
[_detectedImage.layer setMask:shapeLayer];

UIGraphicsBeginImageContextWithOptions(_detectedImage.layer.frame.size, NO, 0);
[_detectedImage.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
UIImage *cpImage = [outputImage imageByTrimmingTransparentPixelsRequiringFullOpacity:YES];
UIGraphicsEndImageContext();

Надеюсь, это кому-то поможет.

person Mayur    schedule 15.12.2016

Просто замените ориентацию на UIImageOrientationUp в следующей строке вашего метода «cropImage».

UIImage *RImage = [UIImage imageWithCGImage:cgImage scale:originalScale orientation:UIImageOrientationUp];
person Krishna Datt Shukla    schedule 01.12.2016