Get back UIImage data after saving it to photo Library in iOS

六月ゝ 毕业季﹏ 提交于 2019-12-08 02:23:52

问题


I got an issue after saving an image created by my app into iPhone Library and trying to get it back. Image data are differents.

Create Image

1.Code

I create an image without using alpha (In fact I got the same result if I use 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.Debug

Here what I got with lldb when I put breaking at the end of the method

(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

Saving Image

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

EDIT : I tried an alternative way to save the image :

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 got the right number of bytes, both error and assetURL are nil in the completion block, and I can't see any new image in the photos album

Get back image from Library

This a delegate method

- (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];
}

Getting back data from previous image

1.Code

+ (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.Debug

Now what I have

(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

An alpha component appears with a value of 255 ... this should not be a problem ? But all others value have changed. And I really don't know how to get the previous value at this point !

EDIT : It seems to be an compression (when saving image) and decompression (when getting it back) problem. But I need to get the exact same data after saving it in the Photos album.


回答1:


Your image is compressed to JPEG before it is saved to photo album. And is decompressed when you are loading it. JPEG is lossy compression. So when you are comparing pixel-data you have differences between original image and compressed/decompressed.

To save lossless try following:

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

For more information about lossless saving/loading to/from photo album please read this thread Saving to/getting JPEG from user gallery without recompression




回答2:


You can't manage a file compare process with saved photos album images because, It automatically embeds few more details with your saved image such as details about location, time etc... when you are saving an image to the photo library. So it will not be same as your input image after the retrieval.



来源:https://stackoverflow.com/questions/21838461/get-back-uiimage-data-after-saving-it-to-photo-library-in-ios

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!