2013-01-31 5 views
13

Ich möchte ein Bild mit einigen Metadatenänderungen in einem temporären Ordner speichern, ohne die eigentlichen Bilddaten neu zu codieren.Originalbilddaten mit modifizierten Metadaten speichern (keine Neucodierung) unter iOS

Die einzige Methode, die ich gefunden habe, ist ALAssetsLibrary/writeImageDataToSavedPhotosAlbum:metadata:completionBlock:, jedoch speichert dieses das Bild in der Fotobibliothek. Stattdessen möchte ich das Bild in einem temporären Ordner speichern (z. B. um es per E-Mail zu teilen, ohne die Fotobibliothek zu füllen).

Ich habe versucht mit CGImageDestinationRef (CGImageDestinationAddImageFromSource), aber es kann nur mit einem decodierten Bild erstellt werden, was bedeutet, es ist es neu zu kodieren, wenn gespeichert (getestet, Pixel Bytes anders aussehen).

Gibt es andere Methoden/Klassen für iOS, die Bilddaten zusammen mit Metadaten speichern können, abgesehen von CGImageDestinationRef? Vorschläge für Workarounds wären ebenfalls willkommen.

+0

Können Sie ein wenig ausarbeiten - wo bekommen Sie die Bilder von (Kamera? Andere?) – foundry

+0

Es spielt keine Rolle, ich habe sie als undecoded 'NSData' (in der Regel von ALAsset gelesen). –

+0

In Anbetracht der Tatsache, dass Sie aus einer Quelle gelesen haben, ist es bereits codiert, aktualisiert die Meta, wie schlägt es fehl, wenn Sie es nur in eine Datei schreiben? Sie wissen, '[Daten writeToFile: atomically:]'. Ich frage mich nur. –

Antwort

12

Dies ist ein frustrierendes Problem mit dem iOS SDK. Zuerst empfehle ich die Einreichung einer enhancement request.

Jetzt ist hier eine mögliche Problemumgehung: WENN der ALAsset von Ihnen erstellt wurde (dh seine editable Eigenschaft ist YES) dann können Sie grundsätzlich die Daten lesen, mit Metadaten schreiben, erneut lesen, auf Festplatte speichern und dann schreiben mit den ursprünglichen Metadaten.

Dieser Ansatz vermeidet die Erstellung eines Duplikats.

Bitte lesen Sie die Kommentare // als ich ein paar Sachen aus Gründen der Kürze ausgelassen (wie ein Metadaten-Wörterbuch Gebäude):

ALAsset* asset; //get your asset, don't use this empty one 
if (asset.editable) { 

    // get the source data 
    ALAssetRepresentation *rep = [asset defaultRepresentation]; 
    Byte *buffer = (Byte*)malloc(rep.size); 
    // add error checking here 
    NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:rep.size error:nil]; 
    NSData *sourceData = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES]; 

    // make your metadata whatever you want 
    // you should use actual metadata, not a blank dictionary 
    NSDictionary *metadataDictionary = [NSDictionary dictionary]; 

    // these are __weak to avoid creating an ARC retain cycle 
    NSData __weak *originalData = sourceData; 
    NSDictionary __weak *originalMetadata = [rep metadata]; 

    [asset setImageData:sourceData 
       metadata:metadataDictionary 
     completionBlock:^(NSURL *assetURL, NSError *error) { 
      //now get your data and write it to file 
      if (!error) { 
       //get your data... 
       NSString *assetPath = [assetURL path]; 
       NSData *targetData = [[NSFileManager defaultManager] contentsAtPath:assetPath]; 

       //...write to file... 
       NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
       NSString *documentPath = [searchPaths lastObject]; 
       NSURL *fileURL = [NSURL fileURLWithPath:documentPath]; 
       [targetData writeToURL:fileURL atomically:YES]; 

       //...and put it back the way it was 
       [asset setImageData:originalData metadata:originalMetadata completionBlock:nil]; 
      } else { 
       // handle error on setting data 
       NSLog(@"ERROR: %@", [error localizedDescription]); 
      } 
     }]; 
} else { 
    // you'll need to make a new ALAsset which you have permission to edit and then try again 

} 

Wie Sie sehen können, wenn die ALAsset nicht von Ihnen gehört, benötigen Sie um einen zu erstellen, der der Bibliothek des Benutzers ein Foto hinzufügt, was genau das ist, was Sie vermeiden wollten. Wie Sie jedoch vielleicht schon vermutet haben, können Sie ein ALAsset nicht aus der Fotobibliothek des Benutzers löschen, selbst wenn es in Ihrer App erstellt wurde. (Fühlen Sie sich frei, eine weitere Verbesserungsanfrage dafür einzureichen.)

Also, wenn das Foto/Bild in Ihrer App erstellt wurde, wird dies für Sie arbeiten.

Wenn nicht, wird eine zusätzliche Kopie erstellt, die der Benutzer löschen muss.

Die einzige Alternative ist, die NSData selbst zu analysieren, was ein Schmerz wäre. Es gibt keine Open-Source-Bibliothek, die mir bekannt ist, um diese Lücke im iOS SDK zu schließen.

+0

Danke. Ich habe eine OpenSource-Bibliothek gefunden, die aber seit einiger Zeit nicht mehr aktualisiert wurde und nur einige der Metadaten unterstützt. –

+0

Wo ist die Bibliothek? Es könnte ein lustiges Projekt sein, es zu aktualisieren. –

+0

Hier ist der Link dafür: http://code.google.com/p/iphone-exif/. Ich habe seine Beschreibung bisher nur gelesen, da sie anscheinend nur für Exif funktioniert. –

2

Try This:

- (void)saveImage: (UIImage*)image 
{ 
    if (image != nil) 
    { 
     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, 
                  NSUserDomainMask, YES); 
     NSString *documentsDirectory = [paths objectAtIndex:0]; 
     NSString* path = [documentsDirectory stringByAppendingPathComponent: 
          @"test.png" ]; 
     NSData* data = UIImagePNGRepresentation(image); 
     [data writeToFile:path atomically:YES]; 
    } 
} 

- (UIImage*)loadImage 
{ 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, 
                 NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString* path = [documentsDirectory stringByAppendingPathComponent: 
         @"test.png" ]; 
    UIImage* image = [UIImage imageWithContentsOfFile:path]; 
    [self sendAction:path]; 
    return image; 
} 
+0

Danke, aber das würde die Bilder neu codieren, außer sie waren ursprünglich PNG, in diesem Fall bin ich mir nicht sicher. –

Verwandte Themen