将UIImage转换为NSData

177

我在我的应用程序中使用这段代码,它可以帮助我发送一张图片。

然而,我有一个带有图片的图像视图。我没有appbundle中的文件,但是我有图片在我这边。我该如何更改下面的代码?有人能告诉我如何将myimage转换为NSData吗?

// Attach an image to the email
NSString *path = [[NSBundle mainBundle] pathForResource:@"rainy" ofType:@"jpg"];
NSData *myData = [NSData dataWithContentsOfFile:path];
[picker addAttachmentData:myData mimeType:@"image/jpeg" fileName:@"rainy"];

2
UIImageJPEGRepresentation和UIImagePNGRepresentation都返回图像的NSData。 - Himanshu Agnihotri
7个回答

289

根据您的图像格式,尝试以下其中之一:

UIImageJPEGRepresentation

以JPEG格式返回指定图像的数据。

NSData * UIImageJPEGRepresentation (
   UIImage *image,
   CGFloat compressionQuality
);

UIImagePNGRepresentation

返回指定图像的PNG格式数据。

NSData * UIImagePNGRepresentation (
   UIImage *image
);

这里是文档

编辑:

如果你想要访问组成UIImage的原始字节,你可以使用这种方法:

CGDataProviderRef provider = CGImageGetDataProvider(image.CGImage);
NSData* data = (id)CFBridgingRelease(CGDataProviderCopyData(provider));
const uint8_t* bytes = [data bytes];

如果您使用ARC,请忽略CFBridgingRelease部分,否则这将为您提供图像RGB像素的低级表示。


9
有没有一种方法可以直接获取数据,不管它已经是什么格式? - devios1
1
Xcode建议我在ARC中使用(id)CFBridgingRelease(CGDataProviderCopyData(provider))来获取由CGDataProviderCopyData返回的CDataRef的所有权。 - mostruash
1
@mostruash:谢谢,我已经修改了我的答案以考虑你的建议。 - sergio
@mostruash:在非ARC情况下,没有所有权的概念;程序员应确保每个对象都被释放以消除其接收到的任何保留。在当前情况下,通过释放“data”,您将确保对象被正确地解除分配:CGDataProviderCopyData为您提供了一个保留计数为1的对象;通过释放该对象,您使其被解除分配。 - sergio
1
这并没有帮助。属性CIImage 仅在使用imageWithCIImage:初始化时设置。此外,这不是直接使用的数据,而是另一个图像表示对象。 - King-Wizard
显示剩余4条评论

166
NSData *imageData = UIImagePNGRepresentation(myImage.image);

4
我正在使用这条线,但是速度非常慢。 - user2128531
5
请注意,使用UIImagePNGRepresentation时,图像标志(例如imageOrientation)会丢失。这就是为什么更喜欢使用UIImageJPEGRepresentation的原因。 - Yony

26

如果你在UIImageView中有一张图片,比如"myImageView",你可以这样做:

使用UIImageJPEGRepresentation()或UIImagePNGRepresentation()将你的图片转换为数据:

NSData *data = UIImagePNGRepresentation(myImageView.image);
//or
NSData *data = UIImageJPEGRepresentation(myImageView.image, 0.8);
//The float param (0.8 in this example) is the compression quality 
//expressed as a value from 0.0 to 1.0, where 1.0 represents 
//the least compression (or best quality).

你也可以将此代码放入 GCD 块中,在另一个线程中执行,在处理过程中显示 UIActivityIndicatorView ...

//*code to show a loading view here*

dispatch_queue_t myQueue = dispatch_queue_create("com.my.queue", DISPATCH_QUEUE_SERIAL);

dispatch_async(myQueue, ^{ 

    NSData *data = UIImagePNGRepresentation(myImageView.image);
    //some code....

    dispatch_async( dispatch_get_main_queue(), ^{
        //*code to hide the loading view here*
    });
});

24

创建图片的引用...

UIImage *rainyImage = [UIImage imageNamed:@"rainy.jpg"];

在图像视图中显示图像...ImageDisplay是ImageView的引用:

imagedisplay.image = rainyImage;

通过传递UIImage引用并提供浮点值压缩质量,将其转换为NSData

NSData *imgData = UIImageJPEGRepresentation(rainyImage, 0.9);

2

Swift 4的解决方案

extension UIImage {
    var data : Data? {
      return cgImage?.dataProvider?.data as Data?
    }
}

cgImage.dataProvider 数据是如何编码的?它似乎与 UIImagePNGRepresentationUIImageJPEGRepresentation 的数据不同,因为它不能用于创建像这样的图像 UIImage(data: imageData) - Manuel
@Manuel 不太确定。我只是将 Sergio 的答案语法转换了一下。Sergio 可能更清楚。 - Charlton Provatas
@Manuel 我认为是因为它使用了CoreGraphics API,所以提供的图像数据表示比UIImageJPEGRepresentation提供的更低级。但我相信这个解决方案保留了图像最初的编码格式,并且不会重新对其进行编码。 - Charlton Provatas

1
使用 if-let 语句块与 Data 一起使用可防止应用程序崩溃和代码的安全执行,因为函数 UIImagePNGRepresentation 返回一个可选值。
if let img = UIImage(named: "TestImage.png") {
    if let data:Data = UIImagePNGRepresentation(img) {
       // Handle operations with data here...         
    }
}

注意:Data是Swift 3类。在Swift 3中使用Data而不是NSData。
通用的图像操作(如png和jpg):
if let img = UIImage(named: "TestImage.png") {  //UIImage(named: "TestImage.jpg")
        if let data:Data = UIImagePNGRepresentation(img) {
               handleOperationWithData(data: data)     
        } else if let data:Data = UIImageJPEGRepresentation(img, 1.0) {
               handleOperationWithData(data: data)     
        }
}

*******
func handleOperationWithData(data: Data) {
     // Handle operations with data here...
     if let image = UIImage(data: data) {
        // Use image...
     }
}

通过使用扩展:
extension UIImage {

    var pngRepresentationData: Data? {
        return UIImagePNGRepresentation(img)
    }

    var jpegRepresentationData: Data? {
        return UIImageJPEGRepresentation(self, 1.0)
    }
}

*******
if let img = UIImage(named: "TestImage.png") {  //UIImage(named: "TestImage.jpg")
      if let data = img.pngRepresentationData {
              handleOperationWithData(data: data)     
      } else if let data = img.jpegRepresentationData {
              handleOperationWithData(data: data)     
     }
}

*******
func handleOperationWithData(data: Data) {
     // Handle operations with data here...
     if let image = UIImage(data: data) {
        // Use image...
     }
}

0
- (void) imageConvert
{
     UIImage *snapshot = self.myImageView.image;
     [self encodeImageToBase64String:snapshot];
}    


call this method for image convert in base 64 
    -(NSString *)encodeImageToBase64String:(UIImage *)image
    {
        return [UIImagePNGRepresentation(image) base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接