3

私のアプリは写真を撮ってカメラロールに保存し、EXIF メタデータを変更できるようにします。

AssetsLibrary を使用して写真を保存および変更します (基になる EXIF を変更する必要があるため、新しい PhotoKit API は使用できません。さらに、これはレガシー アプリであり、変更するには多くのリファクタリングが必要になります)。

私は Xcode 6.3.1 を iOS 8.3 SDK で使用しており、展開ターゲットは 6.1 です。

iOS 8.2 では、これがすべて機能しました。

iOS 8.3 では、メタデータの編集に失敗します。

アプリには、プライバシー設定で写真にアクセスする権限があります。

ユーザーが写真を変更し、アプリが写真を書き換えようとすると、iOS 8.3 では [アプリにこの写真の変更を許可する] ダイアログが表示されるようになりました。このダイアログは、iOS 8.2 では表示されませんでした。[変更] をクリックすると、写真は保存されますが、メタデータは消去されます。setImageData から返されるエラーもありません。写真が編集可能かどうかを確認します。

コードは次のとおりです。

-(void)savePhoto:(ALAsset*)asset
{
    ALAssetRepresentation* rep = [asset defaultRepresentation];
    CGImageRef imageRef = [rep fullResolutionImage];
    UIImage *image = [UIImage imageWithCGImage:imageRef];
    NSData *imageData = UIImageJPEGRepresentation(image, 1.0);

    if ([asset isEditable])
    {
        [asset setImageData:imageData metadata:self.getMetadataDictionary completionBlock:^(NSURL *assetURL, NSError *error)
         {
             if (error!=nil)
                 [self showErrorDialog:error title:@"Error saving photo" ];

             [self closeSaveDialog];
         }];
    }
    else
    {
        [self closeSaveDialog];
        UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Error saving photo" message:@"Photo is not editable" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alertView show];
    }
}

これをデバッグしているときに、UIImageJPEGRepresentation によって写真のサイズが 4 倍に拡大されているコードのバグに気付きました。これは、写真を再サンプリングしていたためです。そのため、元の画像バイトを取得するようにコードを変更し、メタデータを書き直しました。しかし興味深いことに、別のエラーが返されます。今回は setImageData がこのエラーを返します。

説明 : 「ユーザーがアクセスを拒否しました」。

根本的なエラー:「ALAssetsLibraryErrorDomain」コード -3311。

FailureReason : 「ユーザーはアプリケーションによるメディアへのアクセスを拒否しました」。

アプリがアセットを作成し、カメラロールにアクセスできるため、これは奇妙です。

繰り返しますが、このコードは iOS 8.2 で機能します。

-(void)savePhoto:(ALAsset*)asset
{
    ALAssetRepresentation* rep = [asset defaultRepresentation];
    // New way handling updating photos, doesn't modify image data at all, only metadata
    Byte *buffer = (Byte*)malloc((unsigned long)rep.size);
    NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:(NSUInteger)rep.size error:nil];
    NSData *imageData = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];
    if ([asset isEditable])
    {
        [asset setImageData:imageData metadata:self.getMetadataDictionary completionBlock:^(NSURL *assetURL, NSError *error)
         {
             if (error!=nil)
                 [self showErrorDialog:error title:@"Error saving photo" ];

             [self closeSaveDialog];
         }];
    }
    else
    {
        [self closeSaveDialog];
        UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Error saving photo" message:@"Photo is not editable" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alertView show];
    }
}

Apple にバグレポートを提出しましたが、何の返事もありません。

これはこの質問に似ています: setImageData fails in iOS 8.3

誰かがこれの修正を知っていますか?

ありがとう、

4

0 に答える 0