#import <AVFoundation/AVFoundation.h>
#import "YXKPhotoController.h"
#import "AVPlayerDemoPlaybackView.h"
#import "VideoCore.h"
#import "YXKPublishController.h"
@interface YXKPhotoController () <UIImagePickerControllerDelegate, UINavigationControllerDelegate>
{
__weak IBOutlet UIView *photoView;
__weak IBOutlet UIButton *turnCameraButton;
__weak IBOutlet UIButton *lightningButton;
__weak IBOutlet UIButton *cancleButton;
__weak IBOutlet UIButton *photoButton;
__weak IBOutlet UIButton *addPhotoButton;
AVCaptureSession *AVSession;
}
@property (nonatomic, strong) AVCaptureSession *session;
@property (nonatomic) BOOL isFlashLight;
@property (nonatomic, strong) AVCaptureDeviceInput *videoInput;
@property (nonatomic, strong) AVCaptureStillImageOutput *stillImageOutput;
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer;
@end
@implementation YXKPhotoController
- (void) viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
self.tabBarController.tabBar.hidden = NO;
}
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.tabBarController.tabBar.hidden = YES;
}
#pragma mark -- 加载预览图层
- (void) setUpCameraLayer
{
if (self.previewLayer == nil) {
self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session];
UIView * view = photoView;
CALayer * viewLayer = [view layer];
[viewLayer setMasksToBounds:YES];
CGRect bounds = [view bounds];
[self.previewLayer setFrame:bounds];
[self.previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
[viewLayer insertSublayer:self.previewLayer below:[[viewLayer sublayers] objectAtIndex:0]];
}
}
- (void) viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if(self.session)
{
[self.session startRunning];
}
}
- (void)viewDidLoad {
[super viewDidLoad];
[self checkDeviceAuthorizationStatus];
self.isFlashLight = NO;
//这个方法的执行我放在init方法里了
self.session = [[AVCaptureSession alloc] init];
self.videoInput = [[AVCaptureDeviceInput alloc] initWithDevice:[self backCamera] error:nil];
//[self fronCamera]方法会返回一个AVCaptureDevice对象,因为我初始化时是采用前摄像头,所以这么写,具体的实现方法后面会介绍
self.stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
NSDictionary * outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG,AVVideoCodecKey, nil];
//这是输出流的设置参数AVVideoCodecJPEG参数表示以JPEG的图片格式输出图片
[self.stillImageOutput setOutputSettings:outputSettings];
if ([self.session canAddInput:self.videoInput]) {
[self.session addInput:self.videoInput];
}
if ([self.session canAddOutput:self.stillImageOutput]) {
[self.session addOutput:self.stillImageOutput];
}
}
#pragma mark -- 打开闪光灯
- (IBAction)turnButtonClick:(id)sender
{
self.isFlashLight = !self.isFlashLight;
if(self.isFlashLight)
{
[lightningButton setImage:[UIImage imageNamed:@"picker_flash_sel.png"] forState:UIControlStateNormal];
}
else
{
[lightningButton setImage:[UIImage imageNamed:@"picker_flash.png"] forState:UIControlStateNormal];
[self closeFlashLight];
}
}
-(void)openFlashLight
{
AVCaptureDevice * device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if (device.torchMode == AVCaptureTorchModeOff) {
//Create an AV session
AVCaptureSession * session = [[AVCaptureSession alloc]init];
// Create device input and add to current session
AVCaptureDeviceInput * input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
[session addInput:input];
// Create video output and add to current session
AVCaptureVideoDataOutput * output = [[AVCaptureVideoDataOutput alloc]init];
[session addOutput:output];
// Start session configuration
[session beginConfiguration];
[device lockForConfiguration:nil];
// Set torch to on
[device setTorchMode:AVCaptureTorchModeOn];
[device unlockForConfiguration];
[session commitConfiguration];
// Start the session
[session startRunning];
// Keep the session around
[self setSession:self.session];
}
}
- (void) closeFlashLight
{
}
#pragma mark -- 反转摄像头
- (IBAction)turnCameraButtonClick:(id)sender
{
[self toggleCamera];
}
#pragma mark -- 翻转摄像头
- (void)toggleCamera {
// p判断设备上有几个摄像头
NSUInteger cameraCount = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo] count];
if (cameraCount > 1) {
NSError *error;
AVCaptureDeviceInput *newVideoInput;
// 获取当前的摄像头是前置还是后置
AVCaptureDevicePosition position = [[_videoInput device] position];
if (position == AVCaptureDevicePositionBack)
newVideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:[self frontCamera] error:&error];
else if (position == AVCaptureDevicePositionFront)
newVideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:[self backCamera] error:&error];
else
return;
if (newVideoInput != nil) {
// 改变回话的配置前,一定要开启配置,配置完成后提交配置改变
[self.session beginConfiguration];
[self.session removeInput:self.videoInput];
if ([self.session canAddInput:newVideoInput]) {
[self.session addInput:newVideoInput];
[self setVideoInput:newVideoInput];
} else {
[self.session addInput:self.videoInput];
}
// 提交新的配置信息
[self.session commitConfiguration];
} else if (error) {
NSLog(@"toggle carema failed, error = %@", error);
}
}
}
- (IBAction)cancleButtonClick:(id)sender
{
self.tabBarController.selectedIndex = 0;
}
#pragma mark -- 调用摄像头拍照,并且跳转到发布界面
- (IBAction)photoButtonClick:(id)sender
{
[self readImageFromCamera];
}
#pragma mark -- 从摄像头获取照片
- (void) readImageFromCamera
{
AVCaptureConnection * videoConnection = [self.stillImageOutput connectionWithMediaType:AVMediaTypeVideo];
if (!videoConnection) {
NSLog(@"take photo failed!");
return;
}
[self.stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
if (imageDataSampleBuffer == NULL) {
return;
}
NSData * imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
UIImage * image = [UIImage imageWithData:imageData];
NSLog(@"image size = %@",NSStringFromCGSize(image.size));
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.03 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if(self.session)
{
if(self.isFlashLight)
{
[self openFlashLight];
}
[self.session stopRunning];
}
YXKPublishController *publish = [[YXKPublishController alloc] init];
publish.image = image;
[self.navigationController pushViewController:publish animated:YES];
});
}];
}
#pragma mark -- 访问本地照片库
- (IBAction)addPhotoButtonClick:(id)sender
{
[self readImageFromAlbum];
}
#pragma mark -- 从本地读取相册
- (void) readImageFromAlbum
{
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
// 设置类型, 表示仅仅从相册中获取照片
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePicker.delegate = self;
// 设置照片是否允许用户编辑
imagePicker.allowsEditing = NO;
[self presentViewController:imagePicker animated:YES completion:nil];
}
#pragma mark -- 图片完成处理后提交,代理方法UIPickerControllerDelegate
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary<NSString *,id> *)editingInfo
{
YXKPublishController *publish = [[YXKPublishController alloc] init];
publish.image = image;
[self.navigationController pushViewController:publish animated:YES];
}
#pragma mark -- 这是获取前后摄像头对象的方法
- (AVCaptureDevice *)cameraWithPosition:(AVCaptureDevicePosition) position {
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
for (AVCaptureDevice *device in devices) {
if ([device position] == position) {
return device;
}
}
return nil;
}
- (AVCaptureDevice *)frontCamera {
return [self cameraWithPosition:AVCaptureDevicePositionFront];
}
- (AVCaptureDevice *)backCamera {
return [self cameraWithPosition:AVCaptureDevicePositionBack];
}
#pragma mark -- 是否拥有使用摄像头的权限
- (void)checkDeviceAuthorizationStatus
{
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
if (granted) {
dispatch_async(dispatch_get_main_queue(), ^{
[self setUpCameraLayer];
});
}
else {
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertController * alert = [UIAlertController alertControllerWithTitle:nil
message:@"No permission to use Camera, please change privacy settings" preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"Cancel"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction * _Nonnull action) {
[self cancleButtonClick:nil];
}]];
[self presentViewController:alert animated:YES completion:nil];
});
}
}];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
iOS-拍照和调用本地图片
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 不多说,直接上代码 import "ViewController.h" @interface ViewContro...
- 模仿QQ图片选择器,支持多选、选原图和视频的图片选择器,同时有预览功能,长按拖动改变顺序.通过相机拍照录制视频 g...