chuyển đổi UIImage sang NSData


170

Tôi đang sử dụng mã này trong ứng dụng của mình để giúp tôi gửi hình ảnh.

Tuy nhiên, tôi có một hình ảnh với một hình ảnh. Tôi không có tập tin trong appbundle nhưng có hình ảnh bên cạnh tôi. Làm thế nào tôi có thể thay đổi mã dưới đây? Bất cứ ai có thể cho tôi biết làm thế nào tôi có thể chuyển đổi myimagesang 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
UIImageJPEGTrình bày, UIImagePNG Xuất hiện cả hai nsdata của hình ảnh .....
Himanshu Agnihotri

Câu trả lời:


286

Hãy thử một trong những điều sau đây, tùy thuộc vào định dạng hình ảnh của bạn:

UIImageJPEGĐại diện

Trả về dữ liệu cho hình ảnh được chỉ định ở định dạng JPEG.

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

UIImagePNG Xuất hiện

Trả về dữ liệu cho hình ảnh được chỉ định ở định dạng PNG

NSData * UIImagePNGRepresentation (
   UIImage *image
);

Đây là tài liệu .

BIÊN TẬP:

nếu bạn muốn truy cập các byte thô tạo nên UIImage, bạn có thể sử dụng phương pháp này:

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

Điều này sẽ cung cấp cho bạn mức độ đại diện thấp của các pixel RGB hình ảnh. (Bỏ qua CFBridgingReleasebit nếu bạn không sử dụng ARC).


8
Có cách nào để lấy dữ liệu ở bất kỳ định dạng nào không?
devios1

1
Xcode gợi ý tôi sử dụng (id)CFBridgingRelease(CGDataProviderCopyData(provider))để có quyền sở hữu được CDataReftrả về CGDataProviderCopyDatatrong ARC.
mostruash

1
@ mostruash: cảm ơn, tôi đã sửa đổi câu trả lời của mình để tính đến đề xuất của bạn.
sergio

@sergio Tôi không có kinh nghiệm với Obj-C không ARC và tôi tự hỏi liệu việc phát hành datasẽ là đủ hay liệu vẫn còn rò rỉ bộ nhớ.
mostruash

1
Điều này sẽ không giúp đỡ. Thuộc tính CIImage chỉ được đặt nếu nó được khởi tạo với imageWithCIImage :. Ngoài ra, đây không trực tiếp là dữ liệu được sử dụng mà là một đối tượng đại diện hình ảnh khác.
King-Wizard

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

4
Tôi đang sử dụng dòng này nhưng nó rất chậm
user2128531 20/03/13

5
Lưu ý rằng imageFlags (như imageOrientation) bị mất khi sử dụng UIImagePNGRepftimeation. Đó là lý do tại sao UIImageJPEG Xuất hiện được ưu tiên.
Yony

26

Nếu bạn có một hình ảnh bên trong UIImageView, ví dụ "myImageView", bạn có thể làm như sau:

Chuyển đổi hình ảnh của bạn bằng cách sử dụng UIImageJPEGRepftimeation () hoặc UIImagePNGRepftimeation () như thế này:

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).

Bạn cũng có thể đặt mã này bên trong khối GCD và thực thi trong một luồng khác, hiển thị UIActivityTheicatorView trong quá trình ...

//*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

Tạo tham chiếu của hình ảnh ....

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

hiển thị hình ảnh theo quan điểm hình ảnh ... imagedisplay là tài liệu tham khảo của ImageView:

imagedisplay.image = rainyImage;

chuyển đổi nó thành NSDatabằng cách chuyển UIImagetham chiếu và cung cấp chất lượng nén trong các giá trị float:

NSData *imgData = UIImageJPEGRepresentation(rainyImage, 0.9);

2

Giải pháp trong Swift 4

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

Làm thế nào là cgImage.dataProviderdữ liệu được mã hóa? Nó dường như khác với dữ liệu của UIImagePNGRepresentationUIImageJPEGRepresentationbởi vì nó không thể được sử dụng để tạo ra một hình ảnh như vậy UIImage(data: imageData).
Manuel

@Quản lý Không chắc chắn. Tôi vừa chuyển đổi cú pháp từ câu trả lời của Sergio. Có lẽ Sergio sẽ biết rõ hơn.
Charlton Provatas

@Manuel Tôi giả sử vì nó sử dụng API CoreGraphics, nó mang lại sự thể hiện dữ liệu ở mức độ thấp hơn của hình ảnh so với những gì UIImageJPEGRepresentationcung cấp. Nhưng tôi tin rằng giải pháp này bảo tồn định dạng mã hóa ban đầu mà hình ảnh nằm trong và không mã hóa lại.
Charlton Provatas

1

Sử dụng khối if-let với Dữ liệu để ngăn sự cố ứng dụng & thực thi mã an toàn, vì chức năng UIImagePNGRepftimeation trả về một giá trị tùy chọn.

if let img = UIImage(named: "TestImage.png") {
    if let data:Data = UIImagePNGRepresentation(img) {
       // Handle operations with data here...         
    }
}

Lưu ý: Dữ liệu là lớp Swift 3. Sử dụng Dữ liệu thay vì NSData với Swift 3

Các thao tác hình ảnh chung (như cả 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...
     }
}

Bằng cách sử dụng phần mở rộng:

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];
    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.