przekonwertować UIImage na NSData

170

Używam tego kodu w mojej aplikacji, który pomoże mi wysłać obraz.

Jednak mam widok obrazu z obrazem. Nie mam pliku w appbundle, ale mam obraz po swojej stronie. Jak mogę zmienić poniższy kod? Czy ktoś może mi powiedzieć, jak mogę przejść myimagena 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"];
Christina
źródło
2
UIImageJPEGRepresentation, UIImagePNGRepresentation obie zwracają nsdata obrazu .....
Himanshu Agnihotri

Odpowiedzi:

286

Wypróbuj jedną z poniższych opcji, w zależności od formatu obrazu:

UIImageJPEGRepresentation

Zwraca dane dla określonego obrazu w formacie JPEG.

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

UIImagePNGRepresentation

Zwraca dane dla określonego obrazu w formacie PNG

NSData * UIImagePNGRepresentation (
   UIImage *image
);

Tutaj docs .

EDYTOWAĆ:

jeśli chcesz uzyskać dostęp do surowych bajtów, które tworzą UIImage, możesz użyć tego podejścia:

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

Zapewni to niskopoziomową reprezentację pikseli RGB obrazu. (Pomiń ten CFBridgingReleasebit, jeśli nie używasz ARC).

sergio
źródło
8
Czy istnieje sposób, aby po prostu uzyskać dane w jakimkolwiek formacie, w jakim już się znajdują?
devios1
1
Xcode sugeruje, żebym (id)CFBridgingRelease(CGDataProviderCopyData(provider))przejął na własność CDataRefzwrócone przez CGDataProviderCopyDataARC.
mostruash
1
@mostruash: dzięki, zmodyfikowałem moją odpowiedź, aby uwzględnić Twoją sugestię.
sergio
@sergio Nie mam doświadczenia z Obj-C innym niż ARC i zastanawiam się, czy wypuszczenie datawystarczyłoby, czy nadal wystąpiłby wyciek pamięci.
mostruash
1
To nie pomoże. Właściwość CIImage jest ustawiana tylko wtedy, gdy została zainicjowana przy użyciu imageWithCIImage :. Ponadto nie są to bezpośrednio używane dane, ale raczej inny obiekt reprezentujący obraz.
King-Wizard
161
NSData *imageData = UIImagePNGRepresentation(myImage.image);
Źródło
źródło
4
Używam tej linii, ale jest ona bardzo powolna
user2128531
5
Zauważ, że imageFlags (takie jak imageOrientation) gubią się podczas używania UIImagePNGRepresentation. Dlatego preferowana jest reprezentacja UIImageJPEG.
Yony
26

Jeśli masz obraz wewnątrz UIImageView, np. „MyImageView”, możesz wykonać następujące czynności:

Przekonwertuj swój obraz za pomocą UIImageJPEGRepresentation () lub UIImagePNGRepresentation () w następujący sposób:

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

Możesz również umieścić ten kod w bloku GCD i wykonać w innym wątku, pokazując podczas procesu 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*
    });
});
FormigaNinja
źródło
24

Utwórz odniesienie do obrazu ....

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

wyświetlanie obrazu w widoku obrazu ... obraz jest odniesieniem do widoku obrazu :

imagedisplay.image = rainyImage;

przekonwertuj go na NSData, przekazując UIImageodniesienie i podaj jakość kompresji w wartościach zmiennoprzecinkowych:

NSData *imgData = UIImageJPEGRepresentation(rainyImage, 0.9);
Jemythehigh
źródło
2

Rozwiązanie w Swift 4

extension UIImage {
    var data : Data? {
      return cgImage?.dataProvider?.data as Data?
    }
}
Charlton Provatas
źródło
Jak cgImage.dataProviderkodowane są dane? Wydaje się, że różni się od danych UIImagePNGRepresentationi UIImageJPEGRepresentationponieważ nie można go użyć do stworzenia takiego obrazu UIImage(data: imageData).
Manuel
@Manuel Not sure. Właśnie przekonwertowałem składnię z odpowiedzi Sergio. Sergio prawdopodobnie wiedziałby lepiej.
Charlton Provatas
@Manuel Zakładam, że ponieważ używa CoreGraphics API, zapewnia reprezentację danych niższego poziomu niż to, co UIImageJPEGRepresentationzapewnia. Uważam jednak, że to rozwiązanie zachowuje oryginalny format kodowania, w którym znajdował się obraz, i nie koduje go ponownie.
Charlton Provatas
1

Użyj bloku if-let z danymi, aby zapobiec awariom aplikacji i bezpiecznemu wykonywaniu kodu, ponieważ funkcja UIImagePNGRepresentation zwraca wartość opcjonalną.

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

Uwaga: dane są klasy Swift 3. Użyj danych zamiast NSData w Swift 3

Ogólne operacje na obrazach (zarówno png, jak i 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...
     }
}

Korzystając z rozszerzenia:

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...
     }
}
Krunal
źródło
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];
    }
Jayesh Mardiya
źródło