将 UIImage 数据保存到 iOS 中的照片库后取回

Posted

技术标签:

【中文标题】将 UIImage 数据保存到 iOS 中的照片库后取回【英文标题】:Get back UIImage data after saving it to photo Library in iOS 【发布时间】:2014-02-17 20:15:17 【问题描述】:

在将我的应用创建的图像保存到 iPhone 库中并尝试取回它后,我遇到了一个问题。图像数据不同。

创建图像

1.代码

我在不使用 alpha 的情况下创建图像(事实上,如果我使用 alpha,我得到了相同的结果)

+ (UIImage *)createImageFromData:(NSData *)data 
    uint8_t *imageData = (uint8_t *) calloc(WIDTH * HEIGHT * 3, sizeof(uint8_t));
    [data getBytes:imageData];
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL,
                                                              imageData,
                                                              WIDTH * HEIGHT * 3,
                                                              NULL);
    CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;

    CGImageRef imageRef = CGImageCreate(WIDTH,
                                        HEIGHT,
                                        8, // Bits per color component
                                        3 * 8, // Bits per pixel : 1 pixel => 3 component
                                        3 * WIDTH, // bytes per lign (1 byte = 1 component)
                                        colorSpace,
                                        bitmapInfo,
                                        provider,
                                        NULL,
                                        NO,
                                        renderingIntent);
    UIImage *resultImage = [UIImage imageWithCGImage:imageRef];

    return resultImage;

2.调试

当我在方法的末尾加上 break 时,我得到了 lldb 的结果

(lldb) p (int)imageData[0]
(uint8_t) $0 = 102
(lldb) p (int)imageData[1]
(uint8_t) $1 = 116
(lldb) p (int)imageData[2]
(uint8_t) $2 = 121
(lldb) p (int)imageData[3]
(uint8_t) $3 = 112

保存图片

- (IBAction)saveImage:(id)sender 
    UIImageWriteToSavedPhotosAlbum(_image, self,
   @selector(image:didFinishSavingWithError:contextInfo:), nil);

编辑:我尝试了另一种保存图像的方法:

CFDataRef pixelData = CGDataProviderCopyData(CGImageGetDataProvider(self.generatedImageView.image.CGImage));
uint8_t *data = (uint8_t *)CFDataGetBytePtr(pixelData);
NSData *dataToSave = [NSData dataWithBytesNoCopy:data length:CFDataGetLength(pixelData) freeWhenDone:NO];

ALAssetsLibrary *assetLib = [[ALAssetsLibrary alloc] init];
[assetLib writeImageDataToSavedPhotosAlbum:dataToSave metadata:nil completionBlock:^(NSURL *assetURL, NSError *error) 
    NSLog(@"%@", error);
];

DataToSave 得到了正确的字节数,errorassetURL 在完成块中都为零,我在相册中看不到任何新图像

从库中取回图片

这是一个委托方法

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 
    NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType];

    // Handle a still image picked from a photo album
    if (CFStringCompare ((CFStringRef) mediaType, kUTTypeImage, 0)
    == kCFCompareEqualTo) 
        self.image = (UIImage *) [info objectForKey:UIImagePickerControllerOriginalImage];
    
    [self dismissViewControllerAnimated:YES completion:nil];

从上一张图片中取回数据

1.代码

+ (NSData *)createDataFromImage:(UIImage *)image 
    CGImageRef imageRef = [image CGImage];

    CFDataRef pixelData = CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage));
    uint8_t *data = (uint8_t *)CFDataGetBytePtr(pixelData);

    return [NSData dataWithBytesNoCopy:data length:SIZE freeWhenDone:YES];;

2.调试

现在我有什么

(lldb) p (int)data[0]
(int) $4 = 35
(lldb) p (int)data[1]
(int) $5 = 72
(lldb) p (int)data[2]
(int) $6 = 100
(lldb) p (int)data[3]
(int) $7 = 255

出现一个值为 255 的 alpha 分量...这应该不是问题吗?但所有其他价值都发生了变化。而且我现在真的不知道如何获得以前的值!

编辑:这似乎是压缩(保存图像时)和解压缩(取回图像时)的问题。 但我需要在将其保存到相册后获得完全相同的数据。

【问题讨论】:

【参考方案1】:

您的图像在保存到相册之前会被压缩为 JPEG。并在加载时解压缩。 JPEG是有损压缩。因此,当您比较像素数据时,原始图像和压缩/解压缩图像之间存在差异。

要无损保存,请尝试以下操作:

+ (void)saveImageData:(NSData *)data 
    ALAssetsLibrary *assetLib = [[[ALAssetsLibrary alloc] init] autorelease];
    [assetLib writeImageDataToSavedPhotosAlbum:data metadata:nil completionBlock:nil];

有关无损保存/加载到/从相册的更多信息,请阅读此线程Saving to/getting JPEG from user gallery without recompression

【讨论】:

这种情况下,有没有不压缩保存的方法? @KIDdAe 我的回答有帮助吗?你应该知道在这种情况下该怎么做:) 我一试就给你反馈(希望今晚有时间)!这是一个承诺 :) ! 当使用writeImageDataToSavedPhotosAlbum:时,我什至看不到照片被添加到相册中(但在使用其他ALAssetLibrary方法时,如writeImageToSavedPhotosAlbum 我使用的是 ALAssetLibrary,但我不熟悉它。这就是为什么我还发布了指向另一个线程 ***.com/questions/13150017/… 的链接的原因。我希望你能在那里找到解决方案。此外,开始一个新主题并在那里发布您的无效代码可能是一个好主意。【参考方案2】:

您无法管理与保存的相册图像的文件比较过程,因为当您将图像保存到照片库时,它会自动在您保存的图像中嵌入更多细节,例如位置、时间等详细信息.所以检索后不会和你输入的图片一样。

【讨论】:

当我取回像素数据时,我认为这些没有任何影响(因为我有相同的字节数 + alpha 通道)并且我从一开始就每 4 个字节得到值 255(如果有标题就不会这样)

以上是关于将 UIImage 数据保存到 iOS 中的照片库后取回的主要内容,如果未能解决你的问题,请参考以下文章

你可以将 PNG 保存到 iOS5 中的照片库吗?

尝试将图像保存到照片库时,iOS 10 应用程序崩溃

将 UIImage 保存到 Core Data 时出错

把UIImage保存到照片库和沙盒中

将 UIImage 保存为不同的名称

将 UIIMage 中显示的照片自动保存到目录