iOS 以编程方式拍照

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9694859/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 17:17:31  来源:igfitidea点击:

iOS taking photo programmatically

objective-ciosxcodephoto

提问by La bla bla

I know this is possible, saw this in some apps (iGotYa is I believe the most famous). I know how to set up everything for taking photos, saving it and everything. But how can it be done programmatically? just having the user click some button (in the regular view controller) and it will automatically take a picture using the front camera and saving it (or not, just getting it as a UIImage)

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

Thanks!

谢谢!

采纳答案by Pochi

This is very simple, just use the AVFoundationreference guide:

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

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

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

If you don't want the user to see the preview input you can just skip the set preview layer part of the code.

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

Edit: To be more detailed.

编辑:要更详细。

1)You set your capture configuration using the AVFoundation.

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

  • Set the camera input to frontal, turn off flash etc etc.
  • 将相机输入设置为正面,关闭闪光灯等。

2)You SKIP the part where the video preview layer is set.

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

3)You call the captureStillImageAsynchronouslyFromConnection:completionHandler:method whenever you want the picture to be taken.

3)每当您想要拍摄照片时,您都可以调用captureStillImageAsynchronouslyFromConnection:completionHandler:方法。

Note: If you want the flash to not be heard and such then you might be violating the user rights in some countries (japan for example). One workaround I know of to do so is by capturing a frame of a video (does not trigger flash).

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

回答by GrandSteph

You can also do it without AVFoundation and it is in my opinion an easier way to implement it using only the UIImagePickerController. There are 3 conditions:

你也可以在没有 AVFoundation 的情况下做到这一点,在我看来,这是一种仅使用 UIImagePickerController 来实现它的更简单的方法。有3个条件:

  1. Obviously the device needs to have a camera
  2. You must hide the camera controls
  3. Then simply use the takePicture method from UIImagePickerController
  1. 显然设备需要有一个摄像头
  2. 您必须隐藏相机控件
  3. 然后只需使用 UIImagePickerController 中的 takePicture 方法

Below is a simple example that you woul typically trigger after a button push

下面是一个简单的例子,你通常会在按下按钮后触发

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

回答by samwize

VLBCameraViewis a library that uses AVFoundation to take photo.

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

A preview is shown in the view, which you can then call the method VLBCameraView#takePicture programmatically to take a photo.

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

Comes with CocoaPods.

带有 CocoaPods。

回答by Nischal Hada

In .h file

在 .h 文件中

@interface ABCViewController : UIViewController

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

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

@end

In .m file

在 .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];

}

回答by varender singh

Here is the code for Objective -C Custom Camera. You can add features, buttons according to your wish.

这是 Objective -C 自定义相机的代码。您可以根据需要添加功能、按钮。

#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