7

iOSで再圧縮せずにJPEG画像をユーザーギャラリー(カメラロール)に読み書きする方法を見つけようとしています。UIImageがここでのボトルネックのようです。私が見つけたユーザーギャラリーに保存するための唯一のメソッドはUIImageWriteToSavedPhotosAlbum()です。これを回避する方法はありますか?

今のところ私のルーチンはこのように見えます

–UIImagePickerControllerに写真を要求します。そして、それがdidFinishPickingMediaWithInfoになったら、次のようにします。

NSData *imgdata = [NSData dataWithData:UIImageJPEGRepresentation([info objectForKey:@"UIImagePickerControllerOriginalImage"], 1)];
[imgdata writeToFile:filePath atomically:NO];

–ディスク上でJPEGをロスレスで処理します。

–次に保存します。

UIImageWriteToSavedPhotosAlbum([UIImage imageWithContentsOfFile:[self getImagePath]], self, @selector(image:didFinishSavingWithError:contextInfo:), nil);

これは、3パス後の品質低下がどのように見えるかの小さなアニメーションです。

JPEG品質の低下

これを行うたびに明らかに悪化しますが、50/100/1000サイクルで完全にテストするために、画像ピッキング部分を自動化することはできませんでした。

4

1 に答える 1

11

UIImage画像データをデコードして、編集および表示できるようにします。

UIImageWriteToSavedPhotosAlbum([UIImage imageWithContentsOfFile:[NSData dataWithContentsOfFile:[self getImagePath]]], self, @selector(image:didFinishSavingWithError:contextInfo:), nil);

最初に画像をデコードし、次にUIImageWriteToSavedPhotosAlbumメソッドでエンコードして戻します。

代わりに、ALAssetsLibrary / writeImageDataToSavedPhotosAlbum:metadata:completionBlock:を使用する必要があります。

ALAssetsLibrary *assetLib = [[[ALAssetsLibrary alloc] init] autorelease];
[assetLib writeImageDataToSavedPhotosAlbum:[self getImagePath] metadata:nil completionBlock:nil];

メタデータと完了ブロックを呼び出しに渡すこともできます。

編集:

画像を取得するには:

[info objectForKey:@"UIImagePickerControllerOriginalImage"]UIImageから選択されたデコードが含まれUIImagePickerControllerます。代わりに使用する必要があります

NSURL *assetURL = [info objectForKey:UIImagePickerControllerReferenceURL];

を使用すると、 ALAssetsLibrary / assertForURL:resultBlock:failureBlock:メソッドを使用してそれをassetURL取得できるようになります。ALAsset

ALAssetsLibrary *assetLib = [[[ALAssetsLibrary alloc] init] autorelease];
[assetLib assetForURL:assetURL resultBlock:resultBlock failureBlock:failureBlock];

これで、そのイメージの変更されていないNSDataを取得できます。

ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *asset){
  ALAssetRepresentation *assetRep = [asset defaultRepresentation];
  long long imageDataSize = [assetRepresentation size];
  uint8_t* imageDataBytes = malloc(imageDataSize);
  [assetRepresentation getBytes:imageDataBytes fromOffset:0 length:imageDataSize error:nil];
  NSData *imageData = [NSData dataWithBytesNoCopy:imageDataBytes length:imageDataSize freeWhenDone:YES]; // you could for instance read data in smaller buffers and append them to your file instead of reading it all at once
  // save it
  [imgdata writeToFile:filePath atomically:NO];
};
ALAssetsLibraryAccessFailureBlock failureblock  = ^(NSError *myerror){
  NSLog(@"Cannot get image - %@",[myerror localizedDescription]);
  //
};

コードに誤りがあった可能性がありますが、手順は上記のとおりです。何かが正しく機能しない場合、またはこれをもう少し効率的にしたい場合は、stackoverflowや他のサイトNSDataからの読み取りなどを行う例がたくさんあります。ALAsset

于 2013-01-31T07:57:42.663 に答える