Uzyskaj podstawowe NSData z UIImage

104

Mogę tworzyć UIImagez NSDataużyciem [UIImage imageWithData:]lub[UIImage initWithData:] metody.

Zastanawiam się, czy mogę NSDataodzyskać z istniejącej UIImage? Coś na liniiNSData *myData = [myImage getData];

eugene
źródło

Odpowiedzi:

191
NSData *imageData = UIImageJPEGRepresentation(image, 0.7); // 0.7 is JPG quality

lub

NSData *imageData = UIImagePNGRepresentation(image);

W zależności od tego, czy chcesz, aby Twoje dane były w formacie PNG czy JPG.

Karolina
źródło
82
Nie wiem, dlaczego ta odpowiedź jest tak często przegłosowana, ani że jest akceptowana. PO poprosił o pobranie danych, które zostały podane na początku. Użycie UIImageJPEGRepresentationlub UIImagePNGRepresentation spowoduje zmianę danych i dokonanie ponownej konwersji. Czy jest jakiś sposób, aby naprawdę osiągnąć to, o co proszono?
Patrik
6
Ta odpowiedź nie jest dobra, ponieważ obniży jakość obrazu, jeśli jest już w formacie stratnym.
1dayitwillmake
@CipherCom Rozumiem, co mówisz o żądaniu zwrotu dokładnych danych. Jednak myślę, że dla większości osób, które trafią na pytanie, ta odpowiedź będzie idealna dla ich potrzeb… stąd głosy za. Jeśli natkniesz się na odpowiedź na odzyskanie oryginalnych danych, podziel się nią;)
tybro0103
@ 1dayitwillmake Nawet przedstawiciel PNG? To nie moja dziedzina, ale myślałem, że PNG nie ponosi strat?
tybro0103
@Bob Spryn 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
21

Podczas inicjalizacji UIImageobiektu za pomocą init(data: originalData), originalDatazostanie on przekonwertowany na surowe dane w jakimś wewnętrznym formacie. Te dane można pobrać później za pomocą

let rawData = myImage.cgImage?.dataProvider?.data as Data?

Jednak ponieważ rawDatajest surowy, będzie jeszcze większy niż podczas używania UIImagePNGRepresentation.

takleon
źródło
jak to zrobić w Objective-C
h3dkandi
NSData * rawData = (__bridge NSData *) CGDataProviderCopyData (CGImageGetDataProvider (image.CGImage));
ZardozSpeaks
@Zardoz Mówi, że wariant obj-c doskonale nadaje się do dołączenia jako edycja w tej odpowiedzi.
Kamil.S
6

Możesz oczekiwać, że UIImage jest obiektem sformatowanym do wyświetlania, a więc nie będzie używał oryginalnych danych (które prawdopodobnie są w formacie PNG lub JPEG), ale bardziej prawdopodobnie tablicy pikseli lub innego formatu wewnętrznego. Innymi słowy, UIImage(data: foo)nie zachowa foo.

  1. Jeśli chcesz po prostu użyć go w innym miejscu w swoim programie, oryginalny UIImage będzie dobrze (zakładam, że tak nie jest w tym przypadku)

  2. Jeśli chcesz serializować, UIImagePNGRepresentation(...)będzie działać, ale będzie zbyt duży, jeśli oryginał był w formacie JPEG; UIImageJPEGRepresentation(...)często powoduje nieznaczne przewymiarowanie danych i powoduje niewielkie straty, jeśli oryginał był w formacie PNG. Powinno być w porządku, aby wybrać taki w oparciu o sposób wyświetlania obrazu i oczekiwany format. Jeśli korzystasz z PNG i chcesz, aby PNG został usunięty, powinieneś uzyskać dobry rozmiar pliku i prawie identyczne dane, odkładając na bok specjalne fragmenty PNG.

  3. Jeśli chcesz uzyskać dokładną kopię oryginalnych danych (na przykład, aby zapisać plik po utworzeniu miniatury lub do SHA1), musisz zachować je osobno. Możesz zrobić coś takiego:

    var image:UIImage
    var imageData:NSData {
        didSet {
            image = UIImage(data: imageData)
        }
    }
Jim Driscoll
źródło
4

Tylko dlatego, że się na to natknąłem i lubię szybki :)

Oto szybkie tłumaczenie postu Caroiline.

var imageData = UIImagePNGRepresentation(image)

Lub

var imageData = UIImageJPEGRepresentation(image, 0.7) 
nsij22
źródło
Pytanie nie dotyczyło szybkości.
Cross_
3

Swift 4.2

let dataPng = image.pngData() // return image as PNG. May return nil if image has no CGImageRef or invalid bitmap format

let dataJpg = image.jpegData(compressionQuality: 1) // return image as JPEG. May return nil if image has no CGImageRef or invalid bitmap format. compression is 0(most)..1(least)
maslovsa
źródło
-2

Sytuacja zmieniła się od czasu udzielenia powyższej odpowiedzi, dla tych, którzy wciąż szukają, ponieważ podzielają obawy CipherCom: iOS 5 dodał właściwość CIImage .

Rafe
źródło
Nie widzę sposobu na użycie CIImage do uzyskania bazowych NSData ... czy coś mi brakuje?
tybro0103
4
To nie pomoże. Właściwość CIImagejest ustawiana tylko wtedy, gdy została zainicjowana za pomocą imageWithCIImage:. Ponadto nie są to bezpośrednio używane dane, ale raczej inny obiekt reprezentujący obraz.
Patrik