UIImagePickerController pixelated image from choosing too quickly, before image fully loaded
-
10-02-2021 - |
题
I am using UIImagePickerController in an iOS app to save an image in context using UIGraphicsBeginImageContext/UIGraphicsBeginImageContextWithOptions.
I recently noticed that I picture I had saved and then displayed at a later date was highly pixelated; when I went back with the same code and imported the photo again, I got a great image. After playing with this for a while on my device, I figured out that the quality of the image saved depends on WHEN I pressed the 'Choose' button on the 'Move and Scale' screen.
If the image is a larger image and still loading when I press the button, the image is pixelated... if I wait until the image loads, it is fine. My question is, is there any way I can control when the user presses the 'Choose' button - is there any way to force them to wait until after the image is fully loaded? Or is there another way that would be better to approach this issue?
- (void)choosePhoto {
//NSLog(@"%s", __FUNCTION__);
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.allowsEditing = YES;
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:imagePicker animated:YES];
[imagePicker release];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
//NSLog(@"%s", __FUNCTION__);
[self dismissModalViewControllerAnimated:YES];
UIImage *pickedImage = (UIImage*)[info objectForKey:@"UIImagePickerControllerEditedImage"];
[self setPersonImage:pickedImage];
}
- (void) setPersonImage:(UIImage *)pickedImage {
//NSLog(@"%s", __FUNCTION__);
NSManagedObjectContext *context = [[UIApplication sharedDelegate] managedObjectContext];
PersonImage *oldImage = person.image;
if (oldImage != nil) {
[context deleteObject:(NSManagedObject*)oldImage];
}
if (pickedImage != nil) {
// Create an image object for the new image.
PersonImage *newImageObject = [NSEntityDescription insertNewObjectForEntityForName:@"PersonImage" inManagedObjectContext:context];
[newImageObject setImage:pickedImage];
[person setImage:newImageObject];
}
else {
[person setImage:nil];
}
NSError *error;
if (![context save:&error]) {
exit(-1); // Fail
}
}
解决方案
I suggest you implement your own Crop&Resize view controller.
- set
imagePicker.allowsEditing = NO
. - create your view controller in
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
and pass selected image to your view controller. - push your view controller to image picker:
[picker pushViewController:yourVC animated:YES]
其他提示
The image captured by the iPhone 4 camera is ~5 MB in size and it takes a while to display/render it. One option is to compress the image using UIImageJPEGRepresentation()
.
If you do not want to compress the image, you can use UIWebView to display the images. The UIWebViewDelegate
has a method - (void)webViewDidFinishLoad:(UIWebView *)webView
, that hits after the rendering has been completed. You can enable the choose button in this method (which is disabled initially).