如何制作从UIImagePickerController返回的UIImage的精确副本?

时间:2010-10-05 21:41:58

标签: iphone uiimage rotation uiimagepickercontroller

我对从iPhone相机返回的图像有不同的需求。我的应用程序缩小图像以便上传和显示,最近,我添加了将图像保存到照片应用程序的功能。

起初我将返回的值分配给两个单独的变量,但事实证明它们共享了相同的对象,所以我得到了两个缩小的图像而不是一个满刻度的图像。

在弄清楚你不能做UIImage *copyImage = [myImage copy];之后,我使用 imageWithCGImage 制作了一份副本,如下所示。不幸的是,这不起作用,因为副本(此处为 croppedImage )最终会从原始位置旋转90º。

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{   
    // Resize, crop, and correct orientation issues
    self.originalImage = [info valueForKey:@"UIImagePickerControllerOriginalImage"];
    UIImageWriteToSavedPhotosAlbum(originalImage, nil, nil, nil);
    UIImage *smallImage = [UIImage imageWithCGImage:[originalImage CGImage]]; // UIImage doesn't conform to NSCopy

    // This method is from a category on UIImage based on this discussion:
    // http://discussions.apple.com/message.jspa?messageID=7276709
    // It doesn't rotate smallImage, though: while imageWithCGImage returns
    // a rotated CGImage, the UIImageOrientation remains at UIImageOrientationUp!
    UIImage *fixedImage = [smallImage scaleAndRotateImageFromImagePickerWithLongestSide:480];
    ...
}

有没有办法复制UIImagePickerControllerOriginalImage图像而不在过程中修改它?

5 个答案:

答案 0 :(得分:16)

这似乎有效,但您可能会面临一些内存问题,具体取决于您对newImage的处理方式:

CGImageRef newCgIm = CGImageCreateCopy(oldImage.CGImage);
UIImage *newImage = [UIImage imageWithCGImage:newCgIm scale:oldImage.scale orientation:oldImage.imageOrientation];

答案 1 :(得分:8)

这应该有效:

UIImage *newImage = [UIImage imageWithCGImage:oldImage.CGImage];

答案 2 :(得分:3)

复制支持数据并将其旋转

这个问题以一种略有不同的方式提出了一个关于UIImage的常见问题。基本上,您有两个相关的问题 - 深度复制和旋转。 UIImage只是一个容器,并具有用于显示的orientation属性。 UIImage可以将其支持数据包含为CGImageCIImage,但通常为CGImageCGImage是一个包含指向底层数据的指针的信息结构,如果您阅读了文档,则复制结构不会复制数据。所以......

深度复制

正如我将在下一段中深入复制数据将使图像旋转,因为图像在基础数据中旋转。

UIImage *newImage = [UIImage imageWithData:UIImagePNGRepresentation(oldImage)];

这将复制数据,但需要先设置方向属性,然后再将其设置为UIImageView以便正确显示。

深度复制的另一种方法是绘制上下文并获取结果。假设斑马。

UIGraphicsBeginImageContext(zebra!.size)
zebra!.drawInRect(CGRectMake(0, 0, zebra!.size.width, zebra!.size.height))
let copy = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

深层复制和旋转

Rotating a CGImage已被回答。此旋转图像也是新的CGImage,可用于创建UIImage

答案 3 :(得分:2)

UIImage *newImage = [UIImage imageWithData:UIImagePNGRepresentation(oldImage)];

答案 4 :(得分:0)

我认为你需要创建一个图像上下文(CGContextRef)。使用方法CGContextDrawImage(...)将UIImage.CGImage绘制到上下文中,然后使用CGBitmapContextCreateImage(...)从上下文中获取图像。 通过这样的例行程序,我确信您可以获得所需图像的真实副本。希望它对你有所帮助。