【问题标题】:Saving to/getting JPEG from user gallery without recompression无需重新压缩即可从用户图库中保存/获取 JPEG
【发布时间】:2012-10-20 10:38:15
【问题描述】:

我正在尝试找到一种方法来读取和写入 JPEG 图像到用户画廊(相机胶卷),而无需 iOS 重新压缩它们。 UIImage 似乎是这里的瓶颈。我发现保存到用户图库的唯一方法是 UIImageWriteToSavedPhotosAlbum()。有没有办法解决这个问题?

现在我的日常工作是这样的

——向 UIImagePickerController 请求一张照片。当它做完FinishPickingMediaWithInfo 时,做:

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 次通过后质量下降的小动画:

显然每次我这样做都会变得更糟,但我无法自动化图像拾取部分以对其进行 50/100/1000 个周期的全面测试。

【问题讨论】:

    标签: ios uiimage ios6 uiimagepickercontroller jpeg


    【解决方案1】:

    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"] 包含从UIImagePickerController 中选择的解码UIImage。你应该改用

    NSURL *assetURL = [info objectForKey:UIImagePickerControllerReferenceURL];
    

    使用assetURL,您现在可以使用ALAssetsLibrary/assetForURL:resultBlock:failureBlock: 方法为其获取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 或其他网站上从 ALAsset 中读取 NSData

    【讨论】:

    • 是的,谢谢,我已经发现了 AssetsLibrary 的技巧。希望您的回答对其他人有所帮助。
    猜你喜欢
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 2012-06-14
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多