2013-04-11 4 views
10

Etwas wirklich seltsames passiert, ich versuche, ein Bild mit AVFoundation zu erfassen, scheint die Kamera Rollbild gut, aber die Bildvorschau hat das Bild gedreht um 90 Grad.AVFoundation Bildausrichtung um 90 Grad in der Vorschau aber gut in Kamera rollen

Dies ist der Code ich ein Bild

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

Warum durch die Art und Weise hat die Abstimmung herunterkommen? ist die Lösung so trivial? wenn es ist bitte erleuchte mich! Dies ist ein Ort um zu lernen, nicht gemieden zu werden. Ich versuche mein Bestes zu lernen, genau wie du es irgendwann getan hättest! – Jonathan

+0

Haben Sie diese Vorschau-Sache funktioniert richtig, wenn ja dann pls teilen Sie dies mit uns –

Antwort

43

ja zu erfassen verwenden, geschieht es, wenn Sie Bild im Hochformat-Ausrichtung des Geräts erfassen und das Bild in Ihrer Anwendung verwenden, da die Standardausrichtung des Bildes ist Landschaft in jedem IOS-Gerät, so dass Sie die Ausrichtung des Bildes nach der Auswahl aus der Galerie ändern müssen, um in Ihrer App zu verwenden.

Ich habe Code setzen dieses

Code Objective-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; 
} 

Swift Code

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

zu erreichen
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) 
} 
+0

Dipen, ja, ich landete mit etwas ähnliches. Aber ich habe ein anderes Problem, ich möchte, dass mein gespeichertes Bild auf den Inhalt zugeschnitten wird, den ich in meinem quadratischen Videobehälter anzeige. aber das ist nicht der Fall, es speichert sogar den Teil des Bildes, der nicht in der Box sichtbar ist. – Jonathan

+0

dafür müssen Sie einige Schnittmethoden verwenden, um Bilder zu beschneiden, die im QuartzCore-Framework verfügbar sind. –

+0

AUSGEZEICHNET! Danke vielmals!!!! Schon 3 Stunden mit diesem Problem verschwendet. – horseshoe7

1

Die angenommene Antwort funktioniert, ist aber viel komplizierter als es sein muss. Sie können Folgendes verwenden, um das Bild zu drehen.

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

So drehen Sie einfach das Bild und nicht die Ernte, können Sie es einfach wie folgt aufrufen:

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

Funktioniert nicht unter allen Geräteausrichtungen – decades

+0

@decades für welche Ausrichtung und Gerät funktioniert es nicht? Bedenken Sie auch, dass dies die Ausrichtung des Bilds betrifft. Wenn es nicht im Bild aufgezeichnet wird (was ich glaube, dass Sie es manuell einstellen müssen, wenn Sie Ihr eigenes mit den AV-Frameworks erstellen), wird dies nicht funktionieren. – mikeho

+0

Ich habe Ihren Code in Verbindung mit den Ergebnissen von captureStillImageAsynchronouslyFromConnection versucht. Vielleicht lag ich falsch hier – decades