Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/109.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios AVFoundation图像方向在预览中关闭90度,但在摄影机滚动中精细_Ios_Avfoundation - Fatal编程技术网

Ios AVFoundation图像方向在预览中关闭90度,但在摄影机滚动中精细

Ios AVFoundation图像方向在预览中关闭90度,但在摄影机滚动中精细,ios,avfoundation,Ios,Avfoundation,发生了一些非常奇怪的事情,我正在尝试使用AVFoundation拍摄图像,相机的滚动图像看起来很好,但是图像预览将图像旋转了90度 这是我用来捕获图像的代码 AVCaptureConnection *videoConnection = nil; for (AVCaptureConnection *connection in stillImageOutput.connections) { for (AVCaptureInputPort *port in [connection inputP

发生了一些非常奇怪的事情,我正在尝试使用AVFoundation拍摄图像,相机的滚动图像看起来很好,但是图像预览将图像旋转了90度

这是我用来捕获图像的代码

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

//NSLog(@"about to request a capture from: %@", stillImageOutput);
[stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error)
 {
     CFDictionaryRef exifAttachments = CMGetAttachment( imageSampleBuffer, kCGImagePropertyExifDictionary, NULL);
     if (exifAttachments)
     {
         // Do something with the attachments.
         //NSLog(@"attachements: %@", exifAttachments);
     } else {
         NSLog(@"no attachments");
     }

     NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];

     UIImage *image = [[UIImage alloc] initWithData:imageData];

     self.vImage.image = image;

     UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
 }];

是的,当您以设备的纵向方向捕获图像并在应用程序中使用该图像时,会发生这种情况,因为任何IOS设备中图像的默认方向都是横向的,因此您需要在从Gallery中拾取图像后更改图像的方向,以便在应用程序中使用

我已经把代码实现了这一点

目标C代码

- (UIImage *)fixOrientationOfImage:(UIImage *)image {

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

    // 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 (image.imageOrientation) {
        case UIImageOrientationDown:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, image.size.width, image.size.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;

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

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

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

        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, image.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, image.size.width, image.size.height,
                                             CGImageGetBitsPerComponent(image.CGImage), 0,
                                             CGImageGetColorSpace(image.CGImage),
                                             CGImageGetBitmapInfo(image.CGImage));
    CGContextConcatCTM(ctx, transform);
    switch (image.imageOrientation) {
        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            // Grr...
            CGContextDrawImage(ctx, CGRectMake(0,0,image.size.height,image.size.width), image.CGImage);
            break;

        default:
            CGContextDrawImage(ctx, CGRectMake(0,0,image.size.width,image.size.height), image.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;
}
func fixOrientationOfImage(image: UIImage) -> UIImage? {
   if image.imageOrientation == .Up {
      return image
   }

   // 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.
   var transform = CGAffineTransformIdentity

   switch image.imageOrientation {
   case .Down, .DownMirrored:
      transform = CGAffineTransformTranslate(transform, image.size.width, image.size.height)
      transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
   case .Left, .LeftMirrored:
      transform = CGAffineTransformTranslate(transform, image.size.width, 0)
      transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
   case .Right, .RightMirrored:
      transform = CGAffineTransformTranslate(transform, 0, image.size.height)
      transform = CGAffineTransformRotate(transform, -CGFloat(M_PI_2))
   default:
      break
   }

   switch image.imageOrientation {
   case .UpMirrored, .DownMirrored:
      transform = CGAffineTransformTranslate(transform, image.size.width, 0)
      transform = CGAffineTransformScale(transform, -1, 1)
   case .LeftMirrored, .RightMirrored:
      transform = CGAffineTransformTranslate(transform, image.size.height, 0)
      transform = CGAffineTransformScale(transform, -1, 1)
   default:
      break
   }

   // Now we draw the underlying CGImage into a new context, applying the transform
   // calculated above.
   guard let context = CGBitmapContextCreate(nil, Int(image.size.width), Int(image.size.height), CGImageGetBitsPerComponent(image.CGImage), 0, CGImageGetColorSpace(image.CGImage), CGImageGetBitmapInfo(image.CGImage).rawValue) else {
      return nil
   }

   CGContextConcatCTM(context, transform)

   switch image.imageOrientation {
   case .Left, .LeftMirrored, .Right, .RightMirrored:
      CGContextDrawImage(context, CGRect(x: 0, y: 0, width: image.size.height, height: image.size.width), image.CGImage)
   default:
      CGContextDrawImage(context, CGRect(origin: .zero, size: image.size), image.CGImage)
   }

   // And now we just create a new UIImage from the drawing context
   guard let CGImage = CGBitmapContextCreateImage(context) else {
      return nil
   }

   return UIImage(CGImage: CGImage)
}
Swift代码

- (UIImage *)fixOrientationOfImage:(UIImage *)image {

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

    // 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 (image.imageOrientation) {
        case UIImageOrientationDown:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, image.size.width, image.size.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;

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

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

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

        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, image.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, image.size.width, image.size.height,
                                             CGImageGetBitsPerComponent(image.CGImage), 0,
                                             CGImageGetColorSpace(image.CGImage),
                                             CGImageGetBitmapInfo(image.CGImage));
    CGContextConcatCTM(ctx, transform);
    switch (image.imageOrientation) {
        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            // Grr...
            CGContextDrawImage(ctx, CGRectMake(0,0,image.size.height,image.size.width), image.CGImage);
            break;

        default:
            CGContextDrawImage(ctx, CGRectMake(0,0,image.size.width,image.size.height), image.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;
}
func fixOrientationOfImage(image: UIImage) -> UIImage? {
   if image.imageOrientation == .Up {
      return image
   }

   // 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.
   var transform = CGAffineTransformIdentity

   switch image.imageOrientation {
   case .Down, .DownMirrored:
      transform = CGAffineTransformTranslate(transform, image.size.width, image.size.height)
      transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
   case .Left, .LeftMirrored:
      transform = CGAffineTransformTranslate(transform, image.size.width, 0)
      transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
   case .Right, .RightMirrored:
      transform = CGAffineTransformTranslate(transform, 0, image.size.height)
      transform = CGAffineTransformRotate(transform, -CGFloat(M_PI_2))
   default:
      break
   }

   switch image.imageOrientation {
   case .UpMirrored, .DownMirrored:
      transform = CGAffineTransformTranslate(transform, image.size.width, 0)
      transform = CGAffineTransformScale(transform, -1, 1)
   case .LeftMirrored, .RightMirrored:
      transform = CGAffineTransformTranslate(transform, image.size.height, 0)
      transform = CGAffineTransformScale(transform, -1, 1)
   default:
      break
   }

   // Now we draw the underlying CGImage into a new context, applying the transform
   // calculated above.
   guard let context = CGBitmapContextCreate(nil, Int(image.size.width), Int(image.size.height), CGImageGetBitsPerComponent(image.CGImage), 0, CGImageGetColorSpace(image.CGImage), CGImageGetBitmapInfo(image.CGImage).rawValue) else {
      return nil
   }

   CGContextConcatCTM(context, transform)

   switch image.imageOrientation {
   case .Left, .LeftMirrored, .Right, .RightMirrored:
      CGContextDrawImage(context, CGRect(x: 0, y: 0, width: image.size.height, height: image.size.width), image.CGImage)
   default:
      CGContextDrawImage(context, CGRect(origin: .zero, size: image.size), image.CGImage)
   }

   // And now we just create a new UIImage from the drawing context
   guard let CGImage = CGBitmapContextCreateImage(context) else {
      return nil
   }

   return UIImage(CGImage: CGImage)
}
Swift 3.0

func fixOrientationOfImage(image: UIImage) -> UIImage? {
    if image.imageOrientation == .up {
        return image
    }

    // 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.
    var transform = CGAffineTransform.identity

    switch image.imageOrientation {
       case .down, .downMirrored:
        transform = transform.translatedBy(x: image.size.width, y: image.size.height)
        transform = transform.rotated(by: CGFloat(Double.pi))
    case .left, .leftMirrored:
        transform = transform.translatedBy(x: image.size.width, y: 0)
        transform = transform.rotated(by:  CGFloat(Double.pi / 2))
    case .right, .rightMirrored:
        transform = transform.translatedBy(x: 0, y: image.size.height)
        transform = transform.rotated(by:  -CGFloat(Double.pi / 2))
    default:
        break
    }

    switch image.imageOrientation {
    case .upMirrored, .downMirrored:
        transform = transform.translatedBy(x: image.size.width, y: 0)
        transform = transform.scaledBy(x: -1, y: 1)
    case .leftMirrored, .rightMirrored:
        transform = transform.translatedBy(x: image.size.height, y: 0)
        transform = transform.scaledBy(x: -1, y: 1)
    default:
        break
    }

    // Now we draw the underlying CGImage into a new context, applying the transform
    // calculated above.
    guard let context = CGContext(data: nil, width: Int(image.size.width), height: Int(image.size.height), bitsPerComponent: image.cgImage!.bitsPerComponent, bytesPerRow: 0, space: image.cgImage!.colorSpace!, bitmapInfo: image.cgImage!.bitmapInfo.rawValue) else {
        return nil
    }

    context.concatenate(transform)

    switch image.imageOrientation {
      case .left, .leftMirrored, .right, .rightMirrored:
        context.draw(image.cgImage!, in: CGRect(x: 0, y: 0, width: image.size.height, height: image.size.width))
       default:
          context.draw(image.cgImage!, in: CGRect(origin: .zero, size: image.size))
    }

    // And now we just create a new UIImage from the drawing context
    guard let CGImage = context.makeImage() else {
        return nil
    }

    return UIImage(cgImage: CGImage)
}

公认的答案是可行的,但比实际需要复杂得多。可以使用以下命令旋转图像

- (UIImage *)cropImage:(UIImage*)image toRect:(CGRect)rect {
    CGFloat (^rad)(CGFloat) = ^CGFloat(CGFloat deg) {
        return deg / 180.0f * (CGFloat) M_PI;
    };

    // determine the orientation of the image and apply a transformation to the crop rectangle to shift it to the correct position
    CGAffineTransform rectTransform;
    switch (image.imageOrientation) {
        case UIImageOrientationLeft:
            rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(90)), 0, -image.size.height);
            break;
        case UIImageOrientationRight:
            rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-90)), -image.size.width, 0);
            break;
        case UIImageOrientationDown:
            rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-180)), -image.size.width, -image.size.height);
            break;
        default:
            rectTransform = CGAffineTransformIdentity;
    };

    // adjust the transformation scale based on the image scale
    rectTransform = CGAffineTransformScale(rectTransform, image.scale, image.scale);

    // apply the transformation to the rect to create a new, shifted rect
    CGRect transformedCropSquare = CGRectApplyAffineTransform(rect, rectTransform);
    // use the rect to crop the image
    CGImageRef imageRef = CGImageCreateWithImageInRect(image.CGImage, transformedCropSquare);
    // create a new UIImage and set the scale and orientation appropriately
    UIImage *result = [UIImage imageWithCGImage:imageRef scale:image.scale orientation:image.imageOrientation];
    // memory cleanup
    CGImageRelease(imageRef);

    return result;
}
要仅旋转图像而不进行裁剪,只需将其称为:

UIImage *image;
[self cropImage:image toRect:rect.bounds];

迪本·潘查萨拉的答案很好,但可能有一个问题。当您处理大图像(例如来自iPhoneX的图像)时,会出现大量内存峰值,这在某些情况下可能是一个问题

所以,也许你想改变这一行:

context.draw(image.cgImage!, in: CGRect(x: 0, y: 0, width: image.size.height, height: image.size.width))
对于一些内存优化的东西。例如,这将在16(4*4)个步骤中中断图像绘制,从而显著减少内存消耗:

let partInAxis: CGFloat = 4
let partWidth = image.size.height/partInAxis
let partHeight = image.size.width/partInAxis
for i in 0...Int(partInAxis)-1 {
   for j in 0...Int(partInAxis)-1 {
      let partialImage = image.cgImage?.cropping(to: CGRect(x: CGFloat(i)*partWidth, y: CGFloat(j)*partHeight, width: partWidth, height: partHeight))
      context.draw(partialImage!, in: CGRect(x: CGFloat(i)*partWidth, y: CGFloat(Int(partInAxis)-1-j)*partHeight, width: partWidth, height: partHeight))
   }
}

请注意,在这种情况下,图像的高度和宽度必须除以4。

顺便问一下,为什么会被否决?解决方案有那么简单吗?如果是,请启发我!这是一个学习不要回避的地方。我正在尽我最大的努力学习,就像你在某个时候会做的那样!如果是的话,请与usDipen分享,是的,我最终使用了类似的东西。但我面临另一个问题,我希望我保存的图像被裁剪成我在方形视频容器中显示的内容。但事实并非如此,它甚至保存了图像在框中不可见的部分。为此,您需要使用一些裁剪方法来裁剪图像,这些方法在QuartzCore框架中可用。@DipenPanchasara-很棒的东西!!你很棒,迪本。我需要一些逻辑方面的帮助。我将它复制到我的项目中并使用它,“瞧”,我的图像被旋转了。耶!但是当执行到达重画部分时,方向不是我所需要的。我试图理解每一步都发生了什么,但还没有理解。我会继续研究,但如果你或其他人能插话并启发我,我会很高兴的。再次感谢这么好的帖子!谢谢你,先生!我已经找了好几天了。。现在我只需要找到代码来修复启动stillImageOutput后UIImageView的伸缩性哈哈。非常感谢你!我用黑屏拍摄image@decades它不适用于哪个方向和设备?另外,请记住,这是在查看图像的方向,因此如果它没有记录到图像中(我相信如果您围绕AV框架构建自己的框架,您必须手动设置),这将不起作用。我正在尝试将您的代码与captureStillImageAsynchronouslyFromConnection的结果结合使用。也许我错了最后的答案17加上我的修改意见是我问题的完美解决方案@几十年有没有办法轮换数据requestImageDataForAsset@TejasPadliya在结果处理程序中,可以使用
[[UIImage alloc]从
NSData
对象实例化
UIImage
initWithData:data]