【问题标题】:Save UIImage, Load it in Wrong Orientation保存 UIImage,以错误的方向加载它
【发布时间】:2011-12-11 22:16:13
【问题描述】:

我正在使用以下代码来保存和加载我从库中选择或使用相机拍摄的图像:

//saving an image
- (void)saveImage:(UIImage*)image:(NSString*)imageName {
    NSData *imageData = UIImagePNGRepresentation(image); //convert image into .png format.
    NSFileManager *fileManager = [NSFileManager defaultManager];//create instance of NSFileManager
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); //create an array and store result of our search for the documents directory in it
    NSString *documentsDirectory = [paths objectAtIndex:0]; //create NSString object, that holds our exact path to the documents directory
    NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.png", imageName]]; //add our image to the path
    [fileManager createFileAtPath:fullPath contents:imageData attributes:nil]; //finally save the path (image)
    NSLog(@"image saved");
}

//loading an image
- (UIImage*)loadImage:(NSString*)imageName {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.png", imageName]];
    return [UIImage imageWithContentsOfFile:fullPath];
}

这就是我将选择的图像设置为在我的UIImageView 中显示的方式:

imgView.image = [info objectForKey:@"UIImagePickerControllerOriginalImage"];

但是,当我选择图像并将其设置为在我的UIImageView 中显示时,这很好,但是当我加载该图像时,它通常是错误的方向。有任何想法吗?有没有人遇到过这种情况或知道我该如何解决?

谢谢。

编辑:

看来,如果您加载一张以纵向倒置拍摄的照片,它会以该方向加载,如果您以横向拍摄一张照片,它会以该方向加载。任何想法如何解决这个问题?无论加载什么方向,它们总是以 UIImageOrientationUp 的形式返回。

【问题讨论】:

  • 只需查看 UIImageOrientationUp 以获取 UIImage 文档。你可以设置 UIImage 对象的 imageOrientation 属性。
  • 我怎样才能应用这个方向呢?我看了一下,似乎只是为了比较,轮换必须手动完成。
  • 您可以这样解决这个问题:[修复图像方向][1] [1]: stackoverflow.com/questions/13393909/…

标签: iphone objective-c ipad uiimageview orientation


【解决方案1】:

根本原因是PNG格式没有图像方向信息,但JPEG格式有。所以解决这个问题的最简单方法是使用 UIImageJPEGRepresentation() 将文件保存为 JPEG 格式

【讨论】:

  • 这解决了我保存的图像无法以正确方向返回的问题 - 尤其是从相机拍摄的图像。使用 JPEG 替代方案的唯一缺点是不保留透明度,对吗?
  • 还需要小心,使用 JPEG 会得到有损图像
  • 所以像this一样旋转它是必要的。
【解决方案2】:

我也遇到过类似的问题,下面是我的解决方法。

在我们保存图片时,我们需要保存图片的方向信息...

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setInteger:[myImage imageOrientation] forKey:@"kImageOrientation"];
[imageOrientation release];

我们加载我们需要的图像以读取其方向信息并将其应用到图像...

UIImage *tempImage = [[UIImage alloc] initWithContentsOfFile:fullPath];
UIImage *orientedImage= [[UIImage alloc] initWithCGImage: tempImage.CGImage scale:1.0 orientation:imageOrientation];
[tempImage release];

orientedImage 是我们需要的。

谢谢,

【讨论】:

  • 即使在 UIImage 被转换为 NSData 并再次返回后,这是否有效?
  • 谢谢,当我终于找到这个答案时,我遇到了奇怪的旋转 6 小时的麻烦。
  • 这解决了我的问题,但只有在我开始使用 ALAsset 方向属性而不是 UIImage 方向属性之后。
  • 在保存到磁盘之前旋转,如this
【解决方案3】:

检查您正在加载的图像的 EXIF 信息,应该有一个方向标签。使用该值将图像旋转到正确的方向。

这个网站应该让你开始。

http://www.impulseadventure.com/photo/exif-orientation.html

(您用来查看照片的应用程序必须内置此功能,这就是您打开照片时看到正确方向的原因)

【讨论】:

  • 啊非常有趣,但是我将如何获取该 exif 方向数据?
【解决方案4】:

也尝试保存图像方向,然后在加载该图像时检查方向是否正确,如果不是,请使用 CGAffineTransform 或任何您想要的方法旋转图像。

【讨论】:

    【解决方案5】:

    您可以使用 Image I/O 将 PNG 图像保存到文件(或 NSMutableData),以相对于原始图像的方向。在下面的示例中,我将 PNG 图像保存到 path 的文件中。

    - (BOOL)savePngFile:(UIImage *)image toPath:(NSString *)path {
        NSData *data = UIImagePNGRepresentation(image);
        int exifOrientation = [UIImage cc_iOSOrientationToExifOrientation:image.imageOrientation];
        NSDictionary *metadata = @{(__bridge id)kCGImagePropertyOrientation:@(exifOrientation)};
        NSURL *url = [NSURL fileURLWithPath:path];
        CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
        if (!source) {
            return NO;
        }
        CFStringRef UTI = CGImageSourceGetType(source);
        CGImageDestinationRef destination = CGImageDestinationCreateWithURL((__bridge CFURLRef)url, UTI, 1, NULL);
        if (!destination) {
            CFRelease(source);
            return NO;
        }
        CGImageDestinationAddImageFromSource(destination, source, 0, (__bridge CFDictionaryRef)metadata);
        BOOL success = CGImageDestinationFinalize(destination);
        CFRelease(destination);
        CFRelease(source);
        return success;
    }
    

    cc_iOSOrientationToExifOrientation:UIImage 类别的方法。

    + (int)cc_iOSOrientationToExifOrientation:(UIImageOrientation)iOSOrientation {
        int exifOrientation = -1;
        switch (iOSOrientation) {
            case UIImageOrientationUp:
                exifOrientation = 1;
                break;
    
            case UIImageOrientationDown:
                exifOrientation = 3;
                break;
    
            case UIImageOrientationLeft:
                exifOrientation = 8;
                break;
    
            case UIImageOrientationRight:
                exifOrientation = 6;
                break;
    
            case UIImageOrientationUpMirrored:
                exifOrientation = 2;
                break;
    
            case UIImageOrientationDownMirrored:
                exifOrientation = 4;
                break;
    
            case UIImageOrientationLeftMirrored:
                exifOrientation = 5;
                break;
    
            case UIImageOrientationRightMirrored:
                exifOrientation = 7;
                break;
    
            default:
                exifOrientation = -1;
        }
        return exifOrientation;
    }
    

    您也可以使用CGImageDestinationCreateWithData 将图像保存到NSMutableData,并在CGImageDestinationCreateWithURL 中传递NSMutableData 而不是NSURL

    【讨论】:

      猜你喜欢
      • 2019-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-07
      • 2012-03-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多