2011-03-03 16 views
9

anda benim kod çalışıyor Ne: Ben Fotoğraf Kitaplığı'ndan JPG veya PNG seçmekiOS: Çok parçalı/form-data kullanım için NSData dönüştürmek, fotoğraf kütüphanesinden bir GIF seçin

(standart ImagePicker yöntemleri kullanılarak) kullanılarak NSData bu görüntü dönüştürmek: Daha sonra parçalı/formu-verileri kullanarak bir sunucuya yayınlamak

self.myImageData = UIImageJPEGRepresentation(myImage, 0.9); 

.

Şimdi orijinal GIF verilerini korurken (aynı zamanda animasyonlu bir GIF kütüphaneye giderken, yine de canlanıyor), bir GIF için de aynısını yapmak istiyorum. didFinishPickingMediaWithInfo yılında

, ben

self.myGIFURL = [info objectForKey:UIImagePickerControllerReferenceURL]. 

İşte bu beni ne elde edebileceğiniz biri örnek kullanarak orijinal GIF URL'sini almak mümkün:

varlıklar-kütüphane: // varlık/asset.GIF? id = 1000000034 & ext = GIF

İşte, NSData içine bu GIF itmeye şimdi denedim iki yolu vardır ve her zaman myIma geData gösterir (boş).

Ben initWithContentsOfURL kullanmayı denedim:

NSString *stringFromURL = [NSString stringWithFormat:@"%@", myGIFURL]; 
NSData *dataFromGIFURL = [[NSData alloc] initWithContentsOfFile: stringFromURL]; 
self.myImageData = dataFromGIFURL; 
[dataFromGIFURL release]; 

Herhangi öneriler:

NSData *dataFromGIFURL = [[NSData alloc] initWithContentsOfURL: myGIFURL]; 
self.myImageData = dataFromGIFURL; 
[dataFromGIFURL release]; 

Sonra initWithContentsOfFile için bir dizeye NSURL dönüştürme çalıştı

? Teşekkürler.

cevap

13

UIImagePickerControllerReferenceURL anahtarı, iOS 4.1'e kadar görünmez. Bu nedenle sorunuzu, iOS'ta yalnızca 4.0'da görünen AssetsLibrary çerçevesini kullanmanın iyi olduğunu düşündüğümden emin değilim. Bu durumda, aşağıdaki kullanabilirsiniz: o zaman,: Size belirtilen URL ile varlık bulmak istersek,

- (void)imagePickerController:(UIImagePickerController *)picker 
     didFinishPickingMediaWithInfo:(NSDictionary *)info 
{ 
    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; 
    [library assetForURL:[info objectForKey:UIImagePickerControllerReferenceURL] 
     resultBlock:^(ALAsset *asset) 
     { 
      ALAssetRepresentation *representation = [asset defaultRepresentation]; 

      NSLog(@"size of asset in bytes: %d", [representation size]); 

      unsigned char bytes[4]; 
      [representation getBytes:bytes fromOffset:0 length:4 error:nil]; 
      NSLog(@"first four bytes: %02x (%c) %02x (%c) %02x (%c) %02x (%c)", 
           bytes[0], bytes[0], 
           bytes[1], bytes[1], 
           bytes[2], bytes[2], 
           bytes[3], bytes[3]); 

      [library autorelease]; 
     } 
     failureBlock:^(NSError *error) 
     { 
      NSLog(@"couldn't get asset: %@", error); 

      [library autorelease]; 
     } 
    ]; 
} 

Yani, bir ALAssetsLibrary oluşturmak (// URL şeması bu varlıklar-kütüphane anlar) Varlığı aldığınızda varsayılan temsilini yakalar ve bunu baytları beslemek için kullanırsınız. Gerçek disk üzerindeki baytlar, kütüphaneden bir disk için varsayılan gösterimi disk biçiminde olurlar.

2011-03-03 23:

Örneğin bir resim seçici gelen Google görüntülerden rastgele yakaladı belirli bir GIF, seçme bana çıkış verir o yöntemle bir temsilci kadar kablolu : 17: 37,451 IPTest [1199: 307] bayt öğenin boyutu: 174960

2011-03-03 23: 17: 37,459 IPTest [1199: 307], ilk dört bayt: 47 (G) 49 (I) 46 (F) 38 (8)

Bu, standart GIF başlığının başlangıcıdır. PNG'leri veya JPG'leri seçmek, PNG ve JPG başlıklarının tanınan ilk dört baytını verir.

DÜZENLEME: daha çok, (veya: uzunluk: tabii ki uygun bir şekilde malloc'd Cı diziye dosya açıklayan bir bayt okuma ALAssetRepresentation kullanabilir, düşünce tamamlamak için, daha sonra NSData + (id) dataWithBytes kullanımı + dataWithBytesNoCopy: length: freeWhenDone :) bunu bir NSData'ya sarmak için.

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String: Any]) { 
    guard let imageURL = info[UIImagePickerControllerReferenceURL] as? URL else { return } 
    guard let asset = PHAsset.fetchAssets(withALAssetURLs: [imageURL], options: nil).lastObject else { return } 

    if picker.sourceType == .photoLibrary || picker.sourceType == .savedPhotosAlbum { 
     let options = PHImageRequestOptions() 
     options.isSynchronous = true 
     options.isNetworkAccessAllowed = false 
     options.deliveryMode = .highQualityFormat 
     PHImageManager.default().requestImageData(for: asset, options: options) { data, uti, orientation, info in 
      guard let info = info else { return } 

      if let error = info[PHImageErrorKey] as? Error { 
       log.error("Cannot fetch data for GIF image: \(error)") 
       return 
      } 

      if let isInCould = info[PHImageResultIsInCloudKey] as? Bool, isInCould { 
       log.error("Cannot fetch data from cloud. Option for network access not set.") 
       return 
      } 

      // do something with data (it is a Data object) 
     } 
    } else { 
     // do something with media taken via camera 
    } 
} 
+0

Vay:

- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { NSURL * refUrl = [info objectForKey:UIImagePickerControllerReferenceURL]; if (refUrl) { PHAsset * asset = [[PHAsset fetchAssetsWithALAssetURLs:@[refUrl] options:nil] lastObject]; if (asset) { PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init]; options.synchronous = YES; options.networkAccessAllowed = NO; options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat; [[PHImageManager defaultManager] requestImageDataForAsset:asset options:options resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) { NSNumber * isError = [info objectForKey:PHImageErrorKey]; NSNumber * isCloud = [info objectForKey:PHImageResultIsInCloudKey]; if ([isError boolValue] || [isCloud boolValue] || ! imageData) { // fail } else { // success, data is in imageData } }]; } } } 

+0

Çalıştı! “Belli ki yapabiliyorsun ...” bölümü biraz zaman aldı. (Ben bunun için yeniyim.) –

+0

Oh, pardon! Ben sadece baytları almakla uğraştığımı, ancak sorunun NSData kısmına cevap vermeyi unuttuğumun farkına vardım ve bir şeyleri çözmek için geri döndüm. Daha fazla dikkat etmeliydim. Varlık gösterimi tarafından verilen büyüklükte bir bloğu malolabilirim, varlık temsilini yazıp sonra bir NSData'ya aktarıyorum, hafızanın sahipliğini teslim ediyorum (freeWhenDone :) yoluyla). Ayrıca, doğru depolama alanına sahip bir NSMutableData oluşturabilir ve daha sonra, varlık temsilinin kendi mutableBytes özelliğine yazmasını sağlayabilirsiniz. Ama eminim şimdi bu şeyleri anladın ... – Tommy

6

İşte yeni Fotoğraflar çerçevesini kullanan bir versiyonu. Tam cevap için teşekkürler. Onu kazmam ve benim için nasıl çalıştığını göreyim.
3

İşte Swift 3'ü kullanarak Eli sürümü:
İlgili konular