从包含CGImage的UIImage对象获取NSData

时间:2014-03-02 23:12:04

标签: ios objective-c uiimage nsdata cgimage

为了将图像文件上传到我的服务器,我需要获取它的NSData。我现在无法做到这一点,因为我的UIImage包含一个CGImage。

让我告诉你我是如何做事的。当用户拍照时,这就是我对拍摄的照片所做的事情:

NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];


UIImage *image = [[UIImage alloc]initWithData:imageData];


   _subLayer = [CALayer layer];


      image = [self selfieCorrection:image];


      image = [self rotate:image andOrientation:image.imageOrientation];


          CGRect cropRectFinal = CGRectMake(cropRect.origin.x, 140, cropRect.size.width, cropRect.size.height);

          CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], cropRectFinal);


_subLayer.contents = (id)[UIImage imageWithCGImage:imageRef].CGImage;

在上面的代码中,我创建了一个UIImage,并使用imageData对象对其进行初始化。我还创建了一个名为_subLayer的图层对象,它将在屏幕上显示最终图像。然后旋转并校正图像的方向,然后设置CGRect来裁剪我想要保留的图像部分。

最重要的部分是最后两个陈述。我使用原始的UIImage创建一个名为imageRef的CGImageRef。然后,在最后一个语句中,我将_subLayer的contents属性设置为等于我的最终图像。

在同一个视图控制器中,在IBAction内部稍微向下我有以下语句帮助我将图像传递给下一个视图控制器:sendFriendsVC.finalPhotoToSend = _subLayer.contents;

finalPhotoToSend是我在下一个视图控制器的头文件中设置的属性,如下所示:

@property (nonatomic, retain) UIImage *finalPhotoToSend;

当我转到下一个视图控制器时数据成功通过,但是当我NSLog finalPhotoToSend时,即使它是一个UIImage,它也会打印到控制台:

<CGImage 0x1563dac0>

为了将照片上传到我的后端服务器服务,它需要我使用NSData创建一个对象。我尝试使用这两种方法从finalPhotoToSend对象中获取NSData:

NSData *imageData = UIImageJPEGRepresentation(finalPhotoToSend, 0.7);

NSData *imageData = UIImagePNGRepresentation(finalPhotoToSend);

但是那些总是在xcode中给我以下错误:

NSInvalidArgumentException', reason: '-[__NSCFType CGImage]: unrecognized selector sent to instance

我不知道该怎么做。我是否应该使用不同的方法从我的UIImage中获取NSData,因为它在技术上持有CGImage?在将数据传递给下一个视图控制器之前,我应该做些不同的事情吗?

为迈克尔编辑:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:self {


    if ([segue.identifier isEqualToString:@"mediaCaptureToSendToFriendsSegue"]) {


    SendToFriendsViewController *sendFriendsVC = segue.destinationViewController;


        sendFriendsVC.finalPhotoToSend = _subLayer.contents;


    }
}

2 个答案:

答案 0 :(得分:3)

我只是想通了。这是我最终用于IBAction方法实现的内容:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:self {


    if ([segue.identifier isEqualToString:@"mediaCaptureToSendToFriendsSegue"]) {


        SendToFriendsViewController *sendFriendsVC = segue.destinationViewController;


        UIImage* image2 = [UIImage imageWithCGImage:(__bridge CGImageRef)(_subLayer.contents)];

        sendFriendsVC.finalPhotoToSend = image2;


    }
}

我是Objective-c的新手,并不完全确定以下语句甚至在做什么:

UIImage* image2 = [UIImage imageWithCGImage:(__bridge CGImageRef)(_subLayer.contents)];

但是xcode建议它并且它有效。现在在下一个视图控制器上,finalPhotoToSend对象NSLogs为UIImage而不是CGImage。

答案 1 :(得分:2)

更好的回答:

您需要真正将UIImage对象(而不是CGImage指针)设置为您声明为UIImage对象的属性。

原件:

如果“finalPhotoToSend”是属性,您应该这样做:

NSData *imageData = UIImageJPEGRepresentation(self.finalPhotoToSend, 0.7);

而不是:

NSData *imageData = UIImageJPEGRepresentation(finalPhotoToSend, 0.7);