在iOS上使用修改后的元数据(无重新编码)保存原始图像数据 [英] Save original image data with modified metadata (no re-encoding) on iOS

查看:464
本文介绍了在iOS上使用修改后的元数据(无重新编码)保存原始图像数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在临时文件夹中保存一些元数据更改的图像,而不重新编码实际的图像数据。

I want to save an image with some metadata changes in a temp folder, without re-encoding the actual image data.

我发现能够的唯一方法这是 ALAssetsLibrary / writeImageDataToSavedPhotosAlbum:metadata:completionBlock:,但是,这个将图像保存到照片库。相反,我想将图像保存到临时文件夹(例如通过电子邮件共享它,而不填充照片库)。

The only method that I found able to do this is ALAssetsLibrary/writeImageDataToSavedPhotosAlbum:metadata:completionBlock:, however, this one saves the image to the Photo Library. Instead, I want to save the image to a temp folder (for instance to share it by email, without populating the Photo Library).

我尝试使用 CGImageDestinationRef CGImageDestinationAddImageFromSource ),但它只能使用解码图像创建,这意味着它在保存时会重新编码(测试时,像素字节看起来不同)。

I've tried using CGImageDestinationRef (CGImageDestinationAddImageFromSource), but it can only be created using a decoded image, which means it's re-encoding it when saved (tested, pixel bytes look different).

除了使用 CGImageDestinationRef 之外,还有其他可用于iOS的方法/类可以保存图像数据和元数据吗?对于变通方法的建议也很受欢迎。

Are there any other methods/classes available for iOS that can save image data along with metadata, besides using CGImageDestinationRef? Suggestions for workarounds would also be welcomed.

推荐答案

这是一个令人沮丧的iOS SDK问题。首先,我建议提交增强请求

This is a frustrating problem with the iOS SDK. First, I recommend filing an enhancement request.

现在,这是一个潜在的解决方法:如果ALAsset是由您创建的(即,其可编辑属性为 YES )那么你基本上可以读取数据,用元数据写入,再次读取,保存到磁盘,然后用原始元数据写入。

Now, here is a potential workaround: IF the ALAsset was created by you (i.e., its editable property is YES) then you can basically read the data, write with metadata, read again, save to disk, and then write with the original metadata.

这种方法将避免创建重复的图像。

This approach will avoid creating a duplicate image.

请阅读//评论,因为我为了简洁起见省略了一些内容(比如构建元数据字典):

Please read the // comments as I skipped some stuff for brevity (like building a metadata dictionary):

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

}

如您所见,如果您不拥有ALAsset,则需要创建一个,这将为用户添加照片库,这正是你想要避免的。但是,正如您可能已经猜到的那样,即使您的应用程序创建了ALAsset,也无法从用户的照片库中删除ALAsset。 (请随意提交另一项增强请求。)

As you can see, if the ALAsset isn't owned by you, you will need to create one, which will add a photo to the user's library, which is exactly what you wanted to avoid. However, as you may have guessed, you cannot delete an ALAsset from the user's photo library, even if your app created it. (Feel free to file another enhancement request for that.)

因此,如果照片/图片是在您的应用中创建的,那么这对您有用。

So, if the photo/image was created in your app, this will work for you.

但如果没有,它将创建一个用户必须删除的附加副本。

But if not, it will create an additional copy the user must delete.

唯一的选择是自己解析NSData ,这将是一种痛苦。我知道没有开源库可以填补iOS SDK中的这个空白。

The only alternative is to parse the NSData yourself, which would be a pain. There is no open-source library that I am aware of to fill this gap in the iOS SDK.

这篇关于在iOS上使用修改后的元数据(无重新编码)保存原始图像数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆