【问题标题】:rotate CGImage on disk using CGImageSource/CGImageDestination?使用 CGImageSource/CGImageDestination 在磁盘上旋转 CGImage?
【发布时间】:2011-05-23 16:58:41
【问题描述】:

我正在开发一个应用程序,该应用程序需要使用UIImagePickerController 拍照,在应用程序中显示它的缩略图,并使用ASIFormDataRequest(来自ASIHTTPRequest)将该图片提交到服务器。

我想使用来自 ASIFormDataRequest 的 setFile:withFileName:andContentType:forKey:,因为根据我的经验,它比尝试使用 UIImageJPEGRepresentation 提交图像并提交原始 NSData 更快。为此,我使用CGImageDestination 并使用 url 创建图像目标,将该图像保存到磁盘,然后将该文件上传到磁盘上。

为了创建缩略图,我使用CGImageSourceCreateThumbnailAtIndex(请参阅docs)并使用我刚刚保存的文件的路径创建图像源。

我的问题是,无论我将什么选项传递给图像目标或缩略图创建调用,我的缩略图总是逆时针旋转 90 度。上传的图像也会旋转。我尝试使用CGImageDestinationSetProperties 明确设置图像选项中的方向,但似乎没有。我发现的唯一解决方案是在内存中旋转图像,但我真的想避免这种情况,因为这样做会使缩略图+保存操作完成所需的时间加倍。理想情况下,我希望能够旋转磁盘上的图像。

我在使用CGImageDestinationCGImageSource 时是否遗漏了什么?我将在下面发布一些代码。

保存图片:

NSURL *filePath = [NSURL fileURLWithPath:self.imagePath];
CGImageRef imageRef = [self.image CGImage];
CGImageDestinationRef ref = CGImageDestinationCreateWithURL((CFURLRef)filePath, kUTTypeJPEG, 1, NULL);
CGImageDestinationAddImage(ref, imageRef, NULL);

NSDictionary *props = [[NSDictionary dictionaryWithObjectsAndKeys:
                        [NSNumber numberWithFloat:1.0], kCGImageDestinationLossyCompressionQuality,
                        nil] retain];
//Note that setting kCGImagePropertyOrientation didn't work here for me

CGImageDestinationSetProperties(ref, (CFDictionaryRef) props);

CGImageDestinationFinalize(ref);
CFRelease(ref);

生成缩略图

CGImageSourceRef imageSource = CGImageSourceCreateWithURL((CFURLRef)filePath, NULL);
if (!imageSource)
    return;

CFDictionaryRef options = (CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
                                            (id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailWithTransform,
                                            (id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailFromImageIfAbsent,
                                            (id)[NSNumber numberWithFloat:THUMBNAIL_SIDE_LENGTH], (id)kCGImageSourceThumbnailMaxPixelSize, nil];
CGImageRef imgRef = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, options);
UIImage *thumb = [UIImage imageWithCGImage:imgRef];

CGImageRelease(imgRef);
CFRelease(imageSource);

然后上传我刚刚使用的图片

[request setFile:path withFileName:fileName andContentType:contentType forKey:@"photo"];

其中path 是使用上述代码保存的文件的路径。

【问题讨论】:

  • 您应该检查您的初始图像是否只是根据其方向进行解释或物理旋转。检查 image.imageSize 和 CGI​​mageGetHeight 和 CGI​​mageGetWidth 是否返回相同的值。还要检查任何元数据。顺便说一句,您使用的 kCGImageSourceCreateThumbnailWithTransform 可能会或可能不会旋转缩略图。做上面的检查,你会希望找出发生了什么。
  • image.size 是 1936x2592,但 CGImageGetWidth 是 2592,CGImageGetHeight 是 1936。看起来它是物理旋转的。您知道一种无需将整个内容加载到图像上下文中即可旋转图像的方法吗?
  • @kevboh UIImageView 是否以正确的方向显示全分辨率图像?如果是,并且您使用 cgcontext 或 catiledlayer 之类的东西,答案是在绘图点自己处理旋转,因为图像本身没有任何问题,否则旋转图像没有意义。缩略图呢?不确定 kCGImageSourceCreateThumbnailWithTransform 以及是否将旋转数据传递给图像。因此,根据我的代码中的 cmets,UIImage 始终返回与正确方向匹配的大小,而 CGImageRefGetxxxx 始终返回 UIImageOrientationUp 方向。
  • 试试这个:UIImage *thumbnail = [UIImage imageWithCGImage:imgRef scale:1.0forientation:UIImageOrientationUp];对于 thumbnail 或 self.image.imageOrientation 而不是 UIImageOrientationUp,取决于 kCGImageSourceCreateThumbnailWithTransform 是 true 还是 false,由您决定。

标签: objective-c cocoa-touch uiimage uiimagepickercontroller javax.imageio


【解决方案1】:

据我所知,在尝试了很多不同的事情之后,目前的公共 API 无法做到这一点,必须在内存中完成。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-19
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    • 2014-03-15
    • 2012-09-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多