【问题标题】:UIImagePickerController returning incorrect image orientationUIImagePickerController 返回不正确的图像方向
【发布时间】:2011-06-26 17:19:12
【问题描述】:

我正在使用 UIImagePickerController 来捕获图像然后存储它。但是,当我尝试重新调整它时,我从这张图片中得到的方向值是不正确的。当我将手机向上举起拍照时,它给了我向左的方向。有人遇到过这个问题吗?

UIImagePickerController 字典显示以下信息:

{
    UIImagePickerControllerMediaMetadata =     {
        DPIHeight = 72;
        DPIWidth = 72;
        Orientation = 3;
        "{Exif}" =         {
            ApertureValue = "2.970853654340484";
            ColorSpace = 1;
            DateTimeDigitized = "2011:02:14 10:26:17";
            DateTimeOriginal = "2011:02:14 10:26:17";
            ExposureMode = 0;
            ExposureProgram = 2;
            ExposureTime = "0.06666666666666667";
            FNumber = "2.8";
            Flash = 32;
            FocalLength = "3.85";
            ISOSpeedRatings =             (
                125
            );
            MeteringMode = 1;
            PixelXDimension = 2048;
            PixelYDimension = 1536;
            SceneType = 1;
            SensingMethod = 2;
            Sharpness = 1;
            ShutterSpeedValue = "3.910431673351467";
            SubjectArea =             (
                1023,
                767,
                614,
                614
            );
            WhiteBalance = 0;
        };
        "{TIFF}" =         {
            DateTime = "2011:02:14 10:26:17";
            Make = Apple;
            Model = "iPhone 3GS";
            Software = "4.2.1";
            XResolution = 72;
            YResolution = 72;
        };
    };
    UIImagePickerControllerMediaType = "public.image";
    UIImagePickerControllerOriginalImage = "<UIImage: 0x40efb50>";
}

但是图片返回imageOrientation == 1;

UIImage *picture = [info objectForKey:UIImagePickerControllerOriginalImage];             

【问题讨论】:

    标签: uiimage orientation uiimagepickercontroller scale


    【解决方案1】:

    我刚开始在自己的应用中解决这个问题。

    我使用了 Trevor Harmon 制作的 UIImage 类别,用于调整图像大小并固定其方向,UIImage+Resize

    然后你可以在-imagePickerController:didFinishPickingMediaWithInfo:做这样的事情

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

    这解决了我的问题。调整大小的图像在视觉上正确定向,并且 imageOrientation 属性报告 UIImageOrientationUp。

    这个缩放/调整大小/裁剪代码有几个版本;我使用了 Trevor 的,因为它看起来很干净,并且包括一些其他的 UIImage 操纵器,我想稍后使用它们。

    【讨论】:

    • 这似乎不适用于符合 ARC 的代码。它失败并出现错误:“'UIImage' 没有可见的@interface 声明选择器'resizedImageWithContentMode:bounds:interpolationQuality:'”
    • 您可能会在 GitHub 上查看由 Marc Charbonneau 维护的此代码的更新版本。 github.com/mbcharbonneau/UIImage-Categories>
    • 即使使用 Marc 的叉子,这仍然不能固定方向。
    • 它总是返回 UIImageOrientationUp。所以这仅适用于方向 UIImageOrientationUp,不适用于其他方向。
    【解决方案2】:

    这是我发现的解决方向问题的方法;为我工作

    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;
    

    【讨论】:

    • 这会给你。收到内存警告。
    • 谢谢,这已经帮我解决了!
    • 不幸的是,它不起作用。新图像完全一样,方向错误
    【解决方案3】:

    我使用以下代码,我已将其放入一个单独的图像实用程序对象文件中,该文件具有许多其他 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; 
    }
    

    然后我打电话给

    UIImage *pickedImage = [info objectForKey:UIImagePickerControllerOriginalImage];
            UIImage *fixedOriginal = [ImageUtil imageWithImage:[mediaInfoDict objectForKey:UIImagePickerControllerOriginalImage] scaledToSizeWithSameAspectRatio:pickedImage.size];
    

    【讨论】:

      【解决方案4】:

      这是一个可以有效解决问题的 Swift sn-p:

      let orientedImage = UIImage(CGImage: initialImage.CGImage, scale: 1, orientation: initialImage.imageOrientation)!
      

      【讨论】:

        【解决方案5】:

        在 iOS 7 中,我需要依赖于 UIImage.imageOrientation 的代码来纠正不同的方向。现在,在 iOS 8.2 中,当我通过 UIImagePickerController 从相册中挑选旧的测试图像时,所有图像的方向都是 UIImageOrientationUp。当我拍摄照片 (UIImagePickerControllerSourceTypeCamera) 时,无论设备方向如何,这些图像也将始终向上。 因此,在这些 iOS 版本之间,显然已经修复了 UIImagePickerController 已经在必要时旋转图像的问题。 您甚至可以注意到,在显示专辑图像时:在瞬间,它们将以原始方向显示,然后以新的向上方向显示。

        【讨论】:

          【解决方案6】:

          唯一对我有用的是重新渲染图像以强制正确的方向。

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-04-13
            • 2015-12-05
            • 2011-03-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-07-11
            • 1970-01-01
            相关资源
            最近更新 更多