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

clo*_*ach 7 iphone rotation uiimagepickercontroller uiimage

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

起初我将返回的值分配给两个单独的变量,但事实证明它们共享同一个对象,因此我得到了两个缩小的图像而不是全尺寸的图像.

在弄清楚你做不到之后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];
    ...
}
Run Code Online (Sandbox Code Playgroud)

有没有一种方法不会在过程中修改它的UIImagePickerControllerOriginalImage图像复制?

zuw*_*han 16

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

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


jkl*_*wyk 8

这应该工作:

UIImage *newImage = [UIImage imageWithCGImage:oldImage.CGImage];
Run Code Online (Sandbox Code Playgroud)

  • 如果`oldImage.scale> 1`,这将失去质量.使用`imageWithCGImage:scale:orientation:`是可取的. (2认同)

Cam*_*mer 5

复制备份数据并旋转它

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

深度复制

正如我将在下一段中介绍的那样,深度复制数据将使图像旋转,因为图像在基础数据中旋转。

UIImage *newImage = [UIImage imageWithData:UIImagePNGRepresentation(oldImage)];
Run Code Online (Sandbox Code Playgroud)

这将复制数据,但需要先设置方向属性,然后再将其交给诸如UIImageView正确显示之类的东西。

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

UIGraphicsBeginImageContext(zebra!.size)
zebra!.drawInRect(CGRectMake(0, 0, zebra!.size.width, zebra!.size.height))
let copy = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
Run Code Online (Sandbox Code Playgroud)

深拷贝和轮换

CGImage已经回答了旋转 a。碰巧这个旋转的图像是一个新的CGImage,可以用来创建一个UIImage.