2016-12-15 25 views
6

Bir resmin meta verilerini güncellerken ve bunu Fotoğraflar kitaplığına geri kaydettiğimde sorun yaşıyorum. Her şey , değiştirildikten sonra görüntü meta verilerinin daha önce var olan eksik girdileri içermesi ve görüntüyü manipüle etme veya fotoğraf kitaplığı değiştirme bloğunu yürütme sırasında herhangi bir hata almıyorum dışında çalışır. Ayrıca, resme geri yazılmadan önce sözlük, orijinal artı hata ayıklayıcısındaki sözlüğüme benziyor.Güncellenmiş görüntüyü PhotoKit'e kaydederken eksik görüntü meta verileri

Sorularım şunlardır: Neyi yanlış yapıyorum

  1. bunun ne olduğunu temizlemek için ek veriler ile mevcut özelliklerini yeniden yazma geri sebep olabilir?
  2. Bunu yapmak için daha iyi, daha kanonik bir yolu var mı? Bir görüntüdeki bazı meta verileri güncellemek için birçok mekaniğe benziyor. Sadece herkesin yapması gereken gibi görünüyor.

DÜZENLEME: Biriktireceğin Exif ve Tiff değerlere önce

mevcuttur. Bu aşağıdaki kodu kullanarak fotoğraflara kaydettikten sonra meta bütünüdür:

["PixelHeight": 2448, "PixelWidth": 3264, "{Exif}": { 
ColorSpace = 1; 
PixelXDimension = 3264; 
PixelYDimension = 2448;}, "Depth": 8, "ProfileName": sRGB IEC61966-2.1, "Orientation": 1, "{TIFF}": { 
Orientation = 1;}, "ColorModel": RGB, "{JFIF}": { 
DensityUnit = 0; 
JFIFVersion =  (
    1, 
    0, 
    1 
); 
XDensity = 72; 
YDensity = 72;}] 

kodu, tüm Swift 3'te, iOS'da test temel iş akışı

olduğunu 10.1:

// Get a mutable copy of the existing Exif meta 
    let mutableMetaData = getMutableMetadataFrom(imageData: data) 

    // Check to see if it has the {GPS} entry, if it does just exit. 
    if let _ = mutableMetaData[kCGImagePropertyGPSDictionary as String] { 
     callback(imageAsset, true, nil) 
     return 
    } 

    // Add the {GPS} tag to the existing metadata 
    let clLocation = media.location!.asCLLocation() 
    mutableMetaData[kCGImagePropertyGPSDictionary as String] = 
     clLocation.asGPSMetaData() 

    // Attach the new metadata to the existing image 
    guard let newImageData = attach(metadata: mutableMetaData, toImageData: data) else { 
      callback(imageAsset, false, nil) 
      return 
    } 

    let editingOptions = PHContentEditingInputRequestOptions() 
    imageAsset.requestContentEditingInput(with: editingOptions) { editingInput, info in 
     guard let editingInput = editingInput else { return } 
     let library = PHPhotoLibrary.shared() 
     let output = PHContentEditingOutput(contentEditingInput: editingInput) 
     output.adjustmentData = PHAdjustmentData(formatIdentifier: "Project", formatVersion: "0.1", 
               data: "Location Adjustment".data(using: .utf8)!) 
     do { 
      try newImageData.write(to: output.renderedContentURL, options: [.atomic]) 
     } catch { 
      callback(imageAsset, false, error) 
      return 
     } 

     library.performChanges({ 
      let changeRequest = PHAssetChangeRequest(for: imageAsset) 
      changeRequest.location = clLocation 
      changeRequest.contentEditingOutput = output 

     }, completionHandler: { success, error in ... ... 
iş akışına

yardımcı yöntemler şunlardır: aynı zamanda

func attach(metadata: NSDictionary, toImageData imageData:Data) -> Data? { 

    guard 
     let imageDataProvider = CGDataProvider(data: imageData as CFData), 
     let cgImage = CGImage(jpegDataProviderSource: imageDataProvider, decode: nil, 
           shouldInterpolate: true, intent: .defaultIntent), 
     let newImageData = CFDataCreateMutable(nil, 0), 
     let type = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, 
                 "image/jpg" as CFString, kUTTypeImage), 
     let destination = CGImageDestinationCreateWithData(newImageData, 
                  (type.takeRetainedValue()), 1, nil) else { 

      return nil 
     } 

    CGImageDestinationAddImage(destination, cgImage, metadata as CFDictionary) 
    CGImageDestinationFinalize(destination) 

    guard 
     let newProvider = CGDataProvider(data: newImageData), 
     let newCGImage = CGImage(jpegDataProviderSource: newProvider, decode: nil, 
           shouldInterpolate: false, intent: .defaultIntent) else { 

      return nil 
    } 

    return UIImageJPEGRepresentation(UIImage(cgImage: newCGImage), 1.0) 
} 

func getMutableMetadataFrom(imageData data : Data) -> NSMutableDictionary { 

    let imageSourceRef = CGImageSourceCreateWithData(data as CFData, nil) 
    let currentProperties = CGImageSourceCopyPropertiesAtIndex(imageSourceRef!, 0, nil) 
    let mutableDict = NSMutableDictionary(dictionary: currentProperties!) 

    return mutableDict 
} 

asGPSMetaData O hiç sorun oldu CoreGraphics ile görüntü veya meta manipülasyon değildi, ben gözden kaçan birkaç şey olduğunu çıkıyor this Gist

cevap

5

bir Swift 3 versiyonunu göründüğünden çok CLLocation bir uzantısıdır: veri ... aslında, bu JFIF ve boyut verileri (JPEG kullanıldığında bir çekirdek grubu dışında bir meta veri arasında en kaldırır

  1. EXIF ​​veya GPS verileri içeren bir veri bir UIImage oluşturulması kaldırır). İçsel temsili sadece ham veriler olacağından, geriye dönük olarak anlamlıdır. Ancak, dokümanlardaki meta verilerle ilgili açık bir ifade bulamadım.
  2. içine, nesnenin bir veri (meta görüntü) elde etmek için ana iki yol önce noktayı göz önüne alındığında Fotoğraflar kütüphane ya bir geçici dosya bunu yazıp PHAssetChangeRequest::creationRequestForAssetFromImage(atFileURL:) ile okumak veya oluşturmak için PHAssetCreationRequest::forAsset kullanmak edildi Bir oluşturma isteği ve sonra verileri fotoğraf olarak eklemek için PHAssetCreationRequest::addResource(with:data:options:) kullanın. Daha az hareketli olan parçaları olduğu için ikincisini seçtim.

Bu yüzden tüm bunlar güzel, özlü ALAssetsLibrary::writeImage(toSavedPhotosAlbum:metadata:completionBlock:)'un yerini alır.bugün itibariyle UIImage meta korumaz -

var assetID: String? 
    PHPhotoLibrary.shared().performChanges({ 
     let creationRequest = PHAssetCreationRequest.forAsset() 
     creationRequest.addResource(with: .photo, data: imageWithMetaData as Data, options: nil) 
     creationRequest.location = clLocation 
     assetID = creationRequest.placeholderForCreatedAsset?.localIdentifier 
    }) { success, error in ... 
+0

Doğru:

Fotoğraflar kütüphanesi için son değişiklik blok bu olarak sona erdi. Dokümanlar bunu yansıtmak için kısa bir süre sonra güncellenecek. – Bobjt

+0

Yine de meta verilerinin korunması için uiimage için bir yol değil, ilgisiz gelebilir ama değil, benimle çıplak. Ben telefon tarafından alınan ekran görüntüleri gibi giriş görüntüleri kullandığınızda GPUImage kullanan bir fotoğraf uygulaması var, bu görüntüyü bozar ama telefonun kam tarafından çekilen bir fotoğraf gibi bir giriş görüntüsü kullanıldığında, o bozmaz, ben ekran görüntüleri fark ettim meta verileri koruyun ama kamera resimleri bunu düzeltmek için herhangi bir yol var mı? @Ray Pendergraph –

+0

Bunun gerçekten bir hata olmadığı için "sabit" olması muhtemel olduğundan emin değilim. Bir UIImage, iOS için (açıkça belgelendirilmemiş, ancak kullanıcı arayüzü çerçeveleriyle nadir olmayan bir ayrım değil) bir görüntünün bellek gösterimidir ve bununla hiçbir meta veri taşımamaktadır. Bu yüzden verileri almak için varlığı kullanmanız gerekecek. Ekran görüntüleri de Exif verilerine sahiptir (GPS verisi yok). –

İlgili konular