简体   繁体   中英

UIImagePickerController camera blank snapshot image

I'm trying to take a picture using the UIImagePickerControllerSourceTypeCamera . When I'm capturing a photo in the snapshot after, I'm getting a blank photo, but if I choose Use photo I can see it I'm my UIImage:

在此输入图像描述 also in the console im getting these error:

: CGAffineTransformInvert: singular matrix.

and

Snapshotting a view that has not been rendered results in an empty snapshot. Ensure your view has been rendered at least once before snapshotting or snapshot after screen updates.

Here is my code:

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
 }

- (void)viewDidAppear:(BOOL)animated {

  [super viewDidAppear:animated];

}

- (void)didReceiveMemoryWarning
{
  [super didReceiveMemoryWarning];
  // Dispose of any resources that can be recreated.
}

- (IBAction)takePhoto:(id)sender
{

if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
    UIImagePickerController *imagePicker =[[UIImagePickerController alloc] init];
    imagePicker.delegate = self;
    imagePicker.sourceType =UIImagePickerControllerSourceTypeCamera;
    imagePicker.mediaTypes = @[(NSString *) kUTTypeImage];
    imagePicker.allowsEditing = NO;
    [self presentViewController:imagePicker
                       animated:YES completion:nil];
    _newMedia = YES;
}
}


 - (IBAction)selectPhoto:(id)sender
 {

if ([UIImagePickerController isSourceTypeAvailable:
     UIImagePickerControllerSourceTypeSavedPhotosAlbum])
{
    UIImagePickerController *imagePicker =
    [[UIImagePickerController alloc] init];
    imagePicker.delegate = self;
    imagePicker.sourceType =
    UIImagePickerControllerSourceTypePhotoLibrary;
    imagePicker.mediaTypes = @[(NSString *) kUTTypeImage];
    imagePicker.allowsEditing = NO;
    [self presentViewController:imagePicker
                       animated:YES completion:nil];
    _newMedia = NO;
}

}

#pragma mark UIImagePickerControllerDelegate

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

[self dismissViewControllerAnimated:YES completion:nil];

if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
    UIImage *image = info[UIImagePickerControllerOriginalImage];

    _imageView.image = image;
    if (_newMedia)
        UIImageWriteToSavedPhotosAlbum(image,
                                       self,


  @selector(image:finishedSavingWithError:contextInfo:),
                                       nil);
}
else if ([mediaType isEqualToString:(NSString *)kUTTypeMovie])
{
    // Code here to support video if enabled
}
}

-(void)image:(UIImage *)image finishedSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
if (error) {
    UIAlertView *alert = [[UIAlertView alloc]
                          initWithTitle: @"Save failed"
                          message: @"Failed to save image"
                          delegate: nil
                          cancelButtonTitle:@"OK"
                          otherButtonTitles:nil];
    [alert show];
}
}

-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
 [self dismissViewControllerAnimated:YES completion:nil];
}

I have tested your code, its working fine. I think the issue you are facing is something related to this issue...

Snapshotting a view that has not been rendered results in an empty snapshot. Ensure your view has been rendered at least once before snapshotting or snapshot after screen updates.

Check this post; this might help you... UIImagePickerController error: Snapshotting a view that has not been rendered results in an empty snapshot in iOS 7

Here is complete code just incase if you are missing something...
ViewController.h

#import <UIKit/UIKit.h>
@interface ViewController : UIViewController <UIImagePickerControllerDelegate, UINavigationControllerDelegate>
@property (nonatomic, weak) IBOutlet UIImageView *imageView;
- (IBAction)takePhoto:(id)sender;
- (IBAction)selectPhoto:(id)sender;
@end



#import "ViewController.h"
@import MobileCoreServices;

@interface ViewController ()
@property (nonatomic, readwrite) BOOL newMedia;
@end

@implementation ViewController
- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

- (void)viewDidAppear:(BOOL)animated {

    [super viewDidAppear:animated];

}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)takePhoto:(id)sender
{

    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
    {
        UIImagePickerController *imagePicker =[[UIImagePickerController alloc] init];
        imagePicker.delegate = self;
        imagePicker.sourceType =UIImagePickerControllerSourceTypeCamera;
        imagePicker.mediaTypes = @[(NSString *) kUTTypeImage];
        imagePicker.allowsEditing = NO;
        [self presentViewController:imagePicker
                           animated:YES completion:nil];
        _newMedia = YES;
    }
}


- (IBAction)selectPhoto:(id)sender
{

    if ([UIImagePickerController isSourceTypeAvailable:
         UIImagePickerControllerSourceTypeSavedPhotosAlbum])
    {
        UIImagePickerController *imagePicker =
        [[UIImagePickerController alloc] init];
        imagePicker.delegate = self;
        imagePicker.sourceType =
        UIImagePickerControllerSourceTypePhotoLibrary;
        imagePicker.mediaTypes = @[(NSString *) kUTTypeImage];
        imagePicker.allowsEditing = NO;
        [self presentViewController:imagePicker
                           animated:YES completion:nil];
        _newMedia = NO;
    }

}

//- (IBAction)takePhoto_

#pragma mark UIImagePickerControllerDelegate

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

    [self dismissViewControllerAnimated:YES completion:nil];

    if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
        UIImage *image = info[UIImagePickerControllerOriginalImage];

        _imageView.image = image;
        if (_newMedia)
            UIImageWriteToSavedPhotosAlbum(image,
                                           self,


                                           @selector(image:finishedSavingWithError:contextInfo:),
                                           nil);
    }
    else if ([mediaType isEqualToString:(NSString *)kUTTypeMovie])
    {
        // Code here to support video if enabled
    }
}

-(void)image:(UIImage *)image finishedSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
    if (error) {
        UIAlertView *alert = [[UIAlertView alloc]
                              initWithTitle: @"Save failed"
                              message: @"Failed to save image"
                              delegate: nil
                              cancelButtonTitle:@"OK"
                              otherButtonTitles:nil];
        [alert show];
    }
}

-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
    [self dismissViewControllerAnimated:YES completion:nil];
}

@end

I found the solution to my problem thanks to DevC's comment pointing me in the right direction. I used an ActionSheet to present the UIImagePickerController , so when clicking a button on it the animation still runs while the picker is opened. I solved it by closing the picker before I run the code that triggers thepicker:

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    [actionSheet dismissWithClickedButtonIndex:999 animated:NO]; //non-existing button index so it doesn't trigger anything again

    // Rest of code here (UIImagePickerController trigger)
}

I encountered the same problem. If I copy the camera code to a new project,it can works well. So I think maybe it not the code's problem. Finally,in my project, I found it caused by a third-party library which is about status bar.

    self.MTStateBar = [[[MTStatusBarOverlay alloc] initWithFrame:CGRectMake(0, 0, 320, 20)] autorelease];

I solved this problem by replacing it. Wish this answer could help you.

UPDATE 3/15:are you using UIActionSheet to show UIImagePickerController? I solved it by replace UIActionSheet by UIAlertController. Because UIAlertView may will cause unexpected bugs.DO NOT USE UIAlertView anymore;)

I think it's a iOS's bug,you can delay 0.5s to present UIImagePickerController , it's working for me

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM