iOS:从照片库中选择一个GIF,转换为NSData以用于multipart/form-data

Chr*_*eta 9 iphone gif nsdata

我的代码目前正在使用什么:

我从照片库中选择了JPG或PNG(使用标准的ImagePicker方法),并使用以下方法将该图像转换为NSData:

self.myImageData = UIImageJPEGRepresentation(myImage, 0.9); 
Run Code Online (Sandbox Code Playgroud)

然后我使用multipart/form-data将其发布到服务器.

我现在想要为GIF做同样的事情,同时保留原始的GIF数据(以便动画GIF进入图书馆,恢复出来仍然是动画).

在didFinishPickingMediaWithInfo中,我可以使用原始GIF的URL

self.myGIFURL = [info objectForKey:UIImagePickerControllerReferenceURL]. 
Run Code Online (Sandbox Code Playgroud)

这是一个可能让我得到的例子:

资产库://asset/asset.GIF ID = 1000000034&EXT = GIF

以下是我现在尝试将此GIF推送到NSData的两种方法,每次myImageData显示(null).

我试过使用initWithContentsOfURL:

NSData *dataFromGIFURL = [[NSData alloc] initWithContentsOfURL: myGIFURL];
self.myImageData = dataFromGIFURL;
[dataFromGIFURL release];
Run Code Online (Sandbox Code Playgroud)

然后我尝试将NSURL转换为initWithContentsOfFile的字符串:

NSString *stringFromURL = [NSString stringWithFormat:@"%@", myGIFURL];
NSData *dataFromGIFURL = [[NSData alloc] initWithContentsOfFile: stringFromURL];
self.myImageData = dataFromGIFURL;
[dataFromGIFURL release];
Run Code Online (Sandbox Code Playgroud)

有什么建议?谢谢.

Tom*_*mmy 13

UIImagePickerControllerReferenceURL键在iOS 4.1之前不会出现.因此,我在你的问题中暗示,使用AssetsLibrary框架是很好的,该框架仅在4.0版本的iOS中出现.在这种情况下,您可以使用以下内容:

- (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];
        }
    ];
}
Run Code Online (Sandbox Code Playgroud)

因此,您创建了一个ALAssetsLibrary,要求它找到指定了URL的资产(它理解assets-library:// URL方案),然后当您获得资产时,您将获取其默认表示并使用它来为您提供字节.它们将是实际的磁盘上字节,来自磁带库的资产的默认表示形式是磁盘形式.

例如,选择我从Google图像中随机抓取的特定GIF,从连接到该代理的代理的图像选择器中获取输出:

2011-03-03 23:17:37.451 IPTest [1199:307]资产大小,以字节为单位:174960

2011-03-03 23:17:37.459 IPTest [1199:307]前四个字节:47(G)49(I)46(F)38(8)

这就是标准GIF标题的开头.选择PNG或JPG可以识别PNG和JPG标头的前四个字节.

编辑:完成这个想法,显然你可以使用ALAssetRepresentation将描述文件的所有字节读入一个适当的malloc'd C数组,然后使用NSData +(id)dataWithBytes:length :(或者更可能的是,+ dataWithBytesNoCopy: length:freeWhenDone :)将其包装成NSData.


Eli*_*rke 6

这是一个使用较新的Photos框架的版本:

- (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
                }
            }];
        }
    }
}
Run Code Online (Sandbox Code Playgroud)