iOS 使用AVFoundation,捕捉靜態(tài)圖像

一、引入AVFoundation框架

添加頭文件

#import <AVFoundation/AVFoundation.h>

二、定義以下對象:

AVCaptureDevice * device;? // 圖像捕捉設(shè)備

AVCaptureDeviceInput * input; // 輸入流

AVCaptureStillImageOutput * output; //輸出流

?AVCaptureSession * session; // 輸入設(shè)備和輸出設(shè)備之間的數(shù)據(jù)傳遞

AVCaptureVideoPreviewLayer * preview; // 預(yù)覽圖層,顯示攝像頭捕捉到的畫面

?UIButton * cameraButton;? // 拍照按鈕

三、初始化對象

//1.實例化捕捉會話

self.session = [[AVCaptureSession alloc]init];

// 將捕捉會話的預(yù)設(shè)設(shè)置為圖像

self.session.sessionPreset = AVCaptureSessionPresetPhoto;

//2.初始化捕捉設(shè)備

//self.device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

self.device = [self backCamera]; ?// 這里使用后置攝像頭

//3.用captureDevice創(chuàng)建輸入流

self.input = [[AVCaptureDeviceInput alloc]initWithDevice:self.device error:nil];

// 將輸入流添加到會話中

if ([self.session canAddInput:self.input]) {

[self.session addInput:self.input];

}

//4.創(chuàng)建媒體數(shù)據(jù)輸出流為靜態(tài)圖像

self.output = [[AVCaptureStillImageOutput alloc]init];

// 將輸出流設(shè)置成JPEG的圖片格式輸出,這里輸出流的設(shè)置參數(shù)AVVideoCodecJPEG參數(shù)表示以JPEG的圖片格式輸出圖片

NSDictionary * outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG,AVVideoCodecKey, nil];

[self.output setOutputSettings:outputSettings];

// 5.將輸出流添加到會話中

if ([self.session canAddOutput:self.output]) {

[self.session addOutput:self.output];

}

// 6. 通過會話創(chuàng)建預(yù)覽圖層

self.preview = [AVCaptureVideoPreviewLayer layerWithSession:self.session];

// 設(shè)置預(yù)覽圖層填充方式

self.preview.videoGravity = AVLayerVideoGravityResizeAspectFill;

CGFloat max = MAX([UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);

CGFloat min = MIN([UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);

// 設(shè)置預(yù)覽圖層的大小

self.preview.frame = CGRectMake(0, 0, min, max);

// 將預(yù)覽圖層放置在最上面

[self.view.layer insertSublayer:self.preview atIndex:0];



- (void)viewDidAppear:(BOOL)animated{

if (self.session) {

[self.session startRunning];

}

}


- (void)viewDidDisappear:(BOOL)animated{

if (self.session) {

[self.session stopRunning];

}

}

四、初始化設(shè)備時,可選擇前置或后置攝影頭;

// 根據(jù)位置獲取前后攝像頭設(shè)備

- (AVCaptureDevice *)cameraWithPosition:(AVCaptureDevicePosition) position {

? ? AVCaptureDeviceDiscoverySession * deviceDiscoverSession = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInWideAngleCamera] mediaType:AVMediaTypeVideo position:position];

? ? NSArray * devices = deviceDiscoverSession.devices;

? ? 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];

}

// 切換攝像頭

- (void)switchDevice{

NSArray *inputs = self.session.inputs;

for ( AVCaptureDeviceInput *input in inputs ) {

AVCaptureDevice *device = input.device;

if ( [device hasMediaType:AVMediaTypeVideo] ) {

AVCaptureDevicePosition position = device.position;

AVCaptureDevice *newCamera = nil;

AVCaptureDeviceInput *newInput = nil;

if (position == AVCaptureDevicePositionFront)

newCamera = [self cameraWithPosition:AVCaptureDevicePositionBack];

else

newCamera = [self cameraWithPosition:AVCaptureDevicePositionFront];

newInput = [AVCaptureDeviceInput deviceInputWithDevice:newCamera error:nil];

[self.session beginConfiguration];

[self.session removeInput:input];

[self.session addInput:newInput];

[self.session commitConfiguration];

break;

}

}

}

五、在拍照按鈕的點(diǎn)擊事件中獲取捕捉到的圖像,并可將其轉(zhuǎn)成base64字符串

- (void)captureStillImage{

AVCaptureConnection * videoConnection = [self.output connectionWithMediaType:AVMediaTypeVideo];

if (!videoConnection) {

NSLog(@"take photo failed!");

return;

}

[self.output captureStillImageAsynchronouslyFromConnection:videoConnection

completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {

if (imageDataSampleBuffer == NULL) {

return;

}

NSData * imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];

UIImage * image = [UIImage imageWithData:imageData];

UIImage * smallImage = [self scaleImage:image toScale:0.5];

NSData * resultImageData = UIImageJPEGRepresentation(smallImage, 1.0);

NSString * imageBase64String = [resultImageData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];

}];

}

P.S. 這里可以將獲取到的圖片進(jìn)行縮??;

// 等比率縮放圖片

- (UIImage *)scaleImage:(UIImage *)image toScale:(float)scaleSize{

UIGraphicsBeginImageContext(CGSizeMake(image.size.width * scaleSize, image.size.height * scaleSize));

[image drawInRect:CGRectMake(0, 0, image.size.width * scaleSize, image.size.height * scaleSize)];

UIImage * scaledImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

return scaledImage;

}

六、橫屏?xí)r,調(diào)整預(yù)覽圖層frame

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {

[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];

CGFloat max = MAX([UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);

CGFloat min = MIN([UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);

if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) {

self.preview.frame = CGRectMake(0, 0, max, min);

}

if (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {

self.preview.frame = CGRectMake(0, 0, max, min);

}

if (toInterfaceOrientation == UIInterfaceOrientationPortrait) {

self.preview.frame = CGRectMake(0, 0, min, max);

}

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 由于我們公司不是專門做直播的, 所以研究直播開發(fā)完全處于興趣愛好,可能很多地方用處理的不是很周到, 所以, 希望大...
    叫我豐叔閱讀 10,449評論 27 76
  • 目錄相機(jī)基本實現(xiàn)步驟捕捉會話——AVCaptureSession捕捉輸入——AVCaptureDeviceInpu...
    cdcyd閱讀 34,611評論 33 163
  • 1、為什么使用二維碼? 在手機(jī)客戶端應(yīng)用里,對二維碼的使用也比較多。常見的功能有物品信息查詢,登錄信息驗證,掃描登...
    方圓幾度閱讀 588評論 0 0
  • /* 自定義相機(jī):四個核心對象;前后攝像頭的對調(diào);拍照和保存;裁剪圖片;水印圖片; */ #import "Two...
    rebeccaBull閱讀 529評論 0 0
  • 昨天是我的今年第二次生日,因為要潤一個月,所以就有了這么一回事,早上和老爸一起去菜市場買菜,買了魚買了牛肉,基本上...
    堅志閱讀 463評論 0 0

友情鏈接更多精彩內(nèi)容