iOS以编程方式拍照

时间:2012-03-14 01:50:56

标签: objective-c ios xcode photo

我知道这是可能的,在一些应用程序中看到了这一点(iGotYa我相信最着名的)。 我知道如何设置拍照,保存和一切的一切。 但是如何以编程方式完成呢?只需让用户点击某个按钮(在常规视图控制器中),它就会自动使用前置摄像头拍摄并保存(或者不是,只是将其作为UIImage)

谢谢!

6 个答案:

答案 0 :(得分:22)

这很简单,只需使用 AVFoundation 参考指南:

https://developer.apple.com/library/ios/#documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/04_MediaCapture.html

如果您不希望用户看到预览输入,您可以跳过代码的设置预览图层部分。

编辑:更详细。

1)使用AVFoundation设置捕获配置。

  • 将相机输入设置为正面,关闭闪光灯等

2)您跳过设置视频预览图层的部分。

3)只要你想拍摄照片,就可以调用 captureStillImageAsynchronouslyFromConnection:completionHandler:方法。

注意:如果您不想听到闪光灯,那么您可能会侵犯某些国家/地区的用户权限(例如日本)。我知道这样做的一个解决方法是捕获视频帧(不触发闪存)。

答案 1 :(得分:15)

你也可以在没有AVFoundation的情况下完成它,在我看来,只使用UIImagePickerController实现它是一种更简单的方法。 有三个条件:

  1. 显然该设备需要一台摄像头
  2. 您必须隐藏相机控件
  3. 然后只需使用UIImagePickerController中的takePicture方法
  4. 下面是一个简单的示例,您通常会在按下按钮后触发

    - (IBAction)takePhoto:(id)sender 
    {
        UIImagePickerController *picker = [[UIImagePickerController alloc] init];
        picker.delegate = self;
        picker.sourceType = UIImagePickerControllerSourceTypeCamera;
        picker.cameraDevice = UIImagePickerControllerCameraDeviceFront;
        picker.showsCameraControls = NO;
        [self presentViewController:picker animated:YES
                         completion:^ {
                             [picker takePicture];
                         }];
    }
    

答案 2 :(得分:2)

VLBCameraView是一个使用AVFoundation拍照的库。

视图中会显示预览,然后您可以通过编程方式调用VLBCameraView#takePicture方法拍摄照片。

附带CocoaPods。

答案 3 :(得分:1)

在.h文件中

@interface ABCViewController : UIViewController

@property (strong, nonatomic) IBOutlet UIImageView *imageView;

- (IBAction)takePhoto:  (UIButton *)sender;
- (IBAction)selectPhoto:(UIButton *)sender;

@end

在.m文件中

@interface ABCViewController : UIViewController <UIImagePickerControllerDelegate, UINavigationControllerDelegate>

- (IBAction)takePhoto:(UIButton *)sender {


if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {

        UIAlertView *myAlertView = [[UIAlertView alloc] initWithTitle:@"Error"
                                                        message:@"Device has no camera"
                                                        delegate:nil
                                                        cancelButtonTitle:@"OK"
                                                        otherButtonTitles: nil];

        [myAlertView show];

    } else {

    UIImagePickerController *picker = [[UIImagePickerController alloc] init];
    picker.delegate = self;
    picker.allowsEditing = YES;
    picker.sourceType = UIImagePickerControllerSourceTypeCamera;

    [self presentViewController:picker animated:YES completion:NULL];

}

}

- (IBAction)selectPhoto:(UIButton *)sender {

    UIImagePickerController *picker = [[UIImagePickerController alloc] init];
    picker.delegate = self;
    picker.allowsEditing = YES;
    picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

    [self presentViewController:picker animated:YES completion:NULL];


}

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {

    UIImage *chosenImage = info[UIImagePickerControllerEditedImage];
    self.imageView.image = chosenImage;

    [picker dismissViewControllerAnimated:YES completion:NULL];

}


- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {

    [picker dismissViewControllerAnimated:YES completion:NULL];

}

答案 4 :(得分:0)

  

以下是Objective -C Custom Camera的代码。你可以添加功能,   根据你的愿望按钮。

#import "CustomCameraVC.h"

@interface CustomCameraVC ()  {
    BOOL frontCamera;
}
@property (strong,nonatomic) AVCaptureSession *captureSession;
@property (strong,nonatomic) AVCaptureStillImageOutput *stillImageOutput;
@property (strong,nonatomic) AVCaptureVideoPreviewLayer *videoPreviewLayer;
@property (weak, nonatomic) IBOutlet UIView *viewCamera;


@end

@implementation CustomCameraVC

- (void)viewDidLoad {
    [super viewDidLoad];        
}

-(void)viewWillAppear:(BOOL)animated  {
    [super viewWillAppear:YES];
    frontCamera = NO;
    [self showCameraWithFrontCamera:frontCamera];

}

-(void)showCameraWithFrontCamera:(BOOL)flag {
    self.captureSession = [[AVCaptureSession alloc]init];
    self.captureSession.sessionPreset = AVCaptureSessionPresetPhoto;
    AVCaptureDevice *captureDevice;
    if(flag)  {
      captureDevice= [self frontCamera];
    }
    else {
      captureDevice= [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    }
    NSError *error = nil;
    AVCaptureDeviceInput *input =   [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];

    [self.captureSession addInput:input];
    self.stillImageOutput = [AVCaptureStillImageOutput new];
    self.stillImageOutput.outputSettings = @{AVVideoCodecKey:AVVideoCodecJPEG};
    [self.captureSession addOutput:_stillImageOutput];
    self.videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];

    self.videoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    self.videoPreviewLayer.connection.videoOrientation = AVCaptureVideoOrientationPortrait;
    [self.viewCamera.layer addSublayer:self.videoPreviewLayer];
    [self.captureSession startRunning];
    self.videoPreviewLayer.frame = self.viewCamera.bounds;
}


- (AVCaptureDevice *)frontCamera {
    NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
    for (AVCaptureDevice *device in devices) {
        if ([device position] == AVCaptureDevicePositionFront) {
            return device;
        }
    }
    return nil;
}


- (IBAction)btnCaptureImagePressed:(id)sender {

     AVCaptureConnection * videoConnection =  [_stillImageOutput connectionWithMediaType:AVMediaTypeVideo];

    [_stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:^(CMSampleBufferRef  _Nullable sampleBuffer, NSError * _Nullable error) {
       NSData *imageData =  [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:sampleBuffer];
        UIImage *image = [[UIImage alloc]initWithData: imageData];
        UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
    }];

}

@end

答案 5 :(得分:0)

这是针对Xamarin iOS的同一任务的C#实现。

    public void TakePhoto(Action<byte[]> getImageBytesAction)
    {
        var picker = new UIImagePickerController();
        picker.PrefersStatusBarHidden();
        picker.SourceType = UIImagePickerControllerSourceType.Camera;
        picker.CameraDevice = UIImagePickerControllerCameraDevice.Rear;
        
        picker.ShowsCameraControls = false;
        picker.CameraCaptureMode = UIImagePickerControllerCameraCaptureMode.Photo;
        picker.CameraFlashMode = UIImagePickerControllerCameraFlashMode.Off;

        picker.FinishedPickingMedia += (object sender, UIImagePickerMediaPickedEventArgs e) =>
        {
            var photo = e.OriginalImage;
            picker.DismissModalViewController(false);
            //var imageSource = ImageSource.FromStream(() => photo.AsJPEG().AsStream());
            //invoke the action when finished taking picture
            var correctedImage = new UIImage(photo.CGImage, 2.0f, UIImageOrientation.Up);   //scaling 2.0 makes image half
            getImageBytesAction.Invoke(correctedImage.AsJPEG().ToArray());
        };
        //open photo picker with TakePicture trigger on load completion (added a delay to let the camera adjust light and focus)
        GetTopViewController().PresentViewController(picker, false, async () => { await Task.Delay(1000); picker.TakePicture(); });
    }