我知道这是可能的,在一些应用程序中看到了这一点(iGotYa我相信最着名的)。 我知道如何设置拍照,保存和一切的一切。 但是如何以编程方式完成呢?只需让用户点击某个按钮(在常规视图控制器中),它就会自动使用前置摄像头拍摄并保存(或者不是,只是将其作为UIImage)
谢谢!
答案 0 :(得分:22)
这很简单,只需使用 AVFoundation 参考指南:
如果您不希望用户看到预览输入,您可以跳过代码的设置预览图层部分。
编辑:更详细。
1)使用AVFoundation设置捕获配置。
2)您跳过设置视频预览图层的部分。
3)只要你想拍摄照片,就可以调用 captureStillImageAsynchronouslyFromConnection:completionHandler:方法。
注意:如果您不想听到闪光灯,那么您可能会侵犯某些国家/地区的用户权限(例如日本)。我知道这样做的一个解决方法是捕获视频帧(不触发闪存)。
答案 1 :(得分:15)
你也可以在没有AVFoundation的情况下完成它,在我看来,只使用UIImagePickerController实现它是一种更简单的方法。 有三个条件:
下面是一个简单的示例,您通常会在按下按钮后触发
- (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(); });
}