问题
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