UIImagePickerController returning incorrect image orientation

前端 未结 6 1939
北荒
北荒 2020-12-25 08:10

I\'m using UIImagePickerController to capture an image and then store it. However, when i try to rescale it, the orientation value i get out of this image is incorrect. When

相关标签:
6条回答
  • 2020-12-25 08:50

    The only thing that worked for me was to re-render the image again which forces the correct orientation.

    if (photo.imageOrientation != .up) {
       UIGraphicsBeginImageContextWithOptions(photo.size, false, 1.0);
       let rect = CGRect(x: 0, y: 0, width: photo.size.width, height: photo.size.height);
       photo.draw(in: rect)
       let newImage = UIGraphicsGetImageFromCurrentImageContext()
       UIGraphicsEndImageContext()
       photo = newImage;
    }
    
    0 讨论(0)
  • 2020-12-25 08:53

    I just started working on this issue in my own app.

    I used the UIImage category that Trevor Harmon crafted for resizing an image and fixing its orientation, UIImage+Resize.

    Then you can do something like this in -imagePickerController:didFinishPickingMediaWithInfo:

    UIImage *pickedImage = [info objectForKey:UIImagePickerControllerEditedImage];
    UIImage *resized = [pickedImage resizedImageWithContentMode:UIViewContentModeScaleAspectFit bounds:pickedImage.size interpolationQuality:kCGInterpolationHigh];
    

    This fixed the problem for me. The resized image is oriented correctly visually and the imageOrientation property reports UIImageOrientationUp.

    There are several versions of this scale/resize/crop code out there; I used Trevor's because it seems pretty clean and includes some other UIImage manipulators that I want to use later.

    0 讨论(0)
  • 2020-12-25 08:53

    Here's a Swift snippet that fixes the problem efficiently:

    let orientedImage = UIImage(CGImage: initialImage.CGImage, scale: 1, orientation: initialImage.imageOrientation)!
    
    0 讨论(0)
  • 2020-12-25 09:03

    I use the following code that I have put in a separate image utility object file that has a bunch of other editing methods for UIImages:

    + (UIImage*)imageWithImage:(UIImage*)sourceImage scaledToSizeWithSameAspectRatio:(CGSize)targetSize
    {
        CGSize imageSize = sourceImage.size;
        CGFloat width = imageSize.width;
        CGFloat height = imageSize.height;
        CGFloat targetWidth = targetSize.width;
        CGFloat targetHeight = targetSize.height;
        CGFloat scaleFactor = 0.0;
        CGFloat scaledWidth = targetWidth;
        CGFloat scaledHeight = targetHeight;
        CGPoint thumbnailPoint = CGPointMake(0.0,0.0);
    
        if (CGSizeEqualToSize(imageSize, targetSize) == NO) {
            CGFloat widthFactor = targetWidth / width;
            CGFloat heightFactor = targetHeight / height;
    
            if (widthFactor > heightFactor) {
                scaleFactor = widthFactor; // scale to fit height
            }
            else {
                scaleFactor = heightFactor; // scale to fit width
            }
    
            scaledWidth  = width * scaleFactor;
            scaledHeight = height * scaleFactor;
    
            // center the image
            if (widthFactor > heightFactor) {
                thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
            }
            else if (widthFactor < heightFactor) {
                thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
            }
        }
    
        CGImageRef imageRef = [sourceImage CGImage];
        CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);
        CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef);
    
        if (bitmapInfo == kCGImageAlphaNone) {
            bitmapInfo = kCGImageAlphaNoneSkipLast;
        }
    
        CGContextRef bitmap;
    
        if (sourceImage.imageOrientation == UIImageOrientationUp || sourceImage.imageOrientation == UIImageOrientationDown) {
            bitmap = CGBitmapContextCreate(NULL, targetWidth, targetHeight, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);
    
        } else {
            bitmap = CGBitmapContextCreate(NULL, targetHeight, targetWidth, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);
    
        }
    
        // In the right or left cases, we need to switch scaledWidth and scaledHeight,
        // and also the thumbnail point
        if (sourceImage.imageOrientation == UIImageOrientationLeft) {
            thumbnailPoint = CGPointMake(thumbnailPoint.y, thumbnailPoint.x);
            CGFloat oldScaledWidth = scaledWidth;
            scaledWidth = scaledHeight;
            scaledHeight = oldScaledWidth;
    
            CGContextRotateCTM (bitmap, M_PI_2); // + 90 degrees
            CGContextTranslateCTM (bitmap, 0, -targetHeight);
    
        } else if (sourceImage.imageOrientation == UIImageOrientationRight) {
            thumbnailPoint = CGPointMake(thumbnailPoint.y, thumbnailPoint.x);
            CGFloat oldScaledWidth = scaledWidth;
            scaledWidth = scaledHeight;
            scaledHeight = oldScaledWidth;
    
            CGContextRotateCTM (bitmap, -M_PI_2); // - 90 degrees
            CGContextTranslateCTM (bitmap, -targetWidth, 0);
    
        } else if (sourceImage.imageOrientation == UIImageOrientationUp) {
            // NOTHING
        } else if (sourceImage.imageOrientation == UIImageOrientationDown) {
            CGContextTranslateCTM (bitmap, targetWidth, targetHeight);
            CGContextRotateCTM (bitmap, -M_PI); // - 180 degrees
        }
    
        CGContextDrawImage(bitmap, CGRectMake(thumbnailPoint.x, thumbnailPoint.y, scaledWidth, scaledHeight), imageRef);
        CGImageRef ref = CGBitmapContextCreateImage(bitmap);
        UIImage* newImage = [UIImage imageWithCGImage:ref];
    
        CGContextRelease(bitmap);
        CGImageRelease(ref);
    
        return newImage; 
    }
    

    And then I call

    UIImage *pickedImage = [info objectForKey:UIImagePickerControllerOriginalImage];
            UIImage *fixedOriginal = [ImageUtil imageWithImage:[mediaInfoDict objectForKey:UIImagePickerControllerOriginalImage] scaledToSizeWithSameAspectRatio:pickedImage.size];
    
    0 讨论(0)
  • 2020-12-25 09:05

    This what I have found for fixing orientation issue; Works for me

    UIImage *initialImage = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
    NSData *data = UIImagePNGRepresentation(self.initialImage);
    
    UIImage *tempImage = [UIImage imageWithData:data];
    UIImage *fixedOrientationImage = [UIImage imageWithCGImage:tempImage.CGImage
                                         scale:initialImage.scale
                                   orientation:self.initialImage.imageOrientation];
    initialImage = fixedOrientationImage;
    
    0 讨论(0)
  • 2020-12-25 09:10

    In iOS 7, I needed code dependent on UIImage.imageOrientation to correct for the different orientations. Now, in iOS 8.2, when I pick my old test images from the album via UIImagePickerController, the orientation will be UIImageOrientationUp for ALL images. When I take a photo (UIImagePickerControllerSourceTypeCamera), those images will also always be upwards, regardless of the device orientation. So between those iOS versions, there obviously has been a fix where UIImagePickerController already rotates the images if neccessary. You can even notice that when the album images are displayed: for a split second, they will be displayed in the original orientation, before they appear in the new upward orientation.

    0 讨论(0)
提交回复
热议问题