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];

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.


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.


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

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) 

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)

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


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.