欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS自定义相机实现拍照、录制视频

程序员文章站 2023-11-27 21:14:40
本文实例为大家分享了ios自定义相机实现拍照、录制视频的具体代码,供大家参考,具体内容如下 使用avfoundation框架。 这里是demo 首先声明以下对象:...

本文实例为大家分享了ios自定义相机实现拍照、录制视频的具体代码,供大家参考,具体内容如下

使用avfoundation框架。

这里是demo

首先声明以下对象:

#import "customecameraviewcontroller.h"
#import <avfoundation/avfoundation.h>
#import <assetslibrary/assetslibrary.h>
 
@interface customecameraviewcontroller ()<avcapturefileoutputrecordingdelegate>
 
{
  // avcapturesession对象来执行输入设备和输出设备之间的数据传递
  avcapturesession *isession;
  //当前设备
  avcapturedevice *idevice;
  //输入设备
  avcapturedeviceinput *ideviceinput;
  //照片输出流
  avcapturestillimageoutput *istillimageoutput;
  //预览图层
  avcapturevideopreviewlayer *ipreviewlayer;
  
}

初始化各对象:

- (void)viewdidload {
  [super viewdidload];
  
  //点击屏幕对焦
  uitapgesturerecognizer *tap = [[uitapgesturerecognizer alloc]initwithtarget:self action:@selector(focustap:)];
  [self.view addgesturerecognizer:tap];
  
  
  isession = [[avcapturesession alloc]init];
  
  nsarray *devicearray = [avcapturedevice deviceswithmediatype:avmediatypevideo];
  for (avcapturedevice *device in devicearray) {
    
    //avcapturedevicepositionback 后置摄像头
    //avcapturedevicepositionfront 前置摄像头
    if (device.position == avcapturedevicepositionback) {
      idevice = device;
    }
  }
  
  
  isession.sessionpreset = [self getsessionpresetfordevice:idevice];
  
  ideviceinput = [[avcapturedeviceinput alloc]initwithdevice:idevice error:nil];
  
  
  ////输出设置。avvideocodecjpeg  输出jpeg格式图片
  istillimageoutput = [[avcapturestillimageoutput alloc]init];
  nsdictionary *outputdic = [nsdictionary dictionarywithobjectsandkeys:avvideocodecjpeg,avvideocodeckey, nil];
  [istillimageoutput setoutputsettings:outputdic];
  
  
  //更改这个设备设置的时候必须先锁定设备,修改完后再解锁,否则崩溃
  [idevice lockforconfiguration:nil];
  if ([idevice isflashmodesupported:avcaptureflashmodeoff]) {
    [idevice setflashmode:avcaptureflashmodeoff];
  }
  if ([idevice isfocusmodesupported:avcapturefocusmodeautofocus]) {
    [idevice setfocusmode:avcapturefocusmodeautofocus];
  }
  if ([idevice iswhitebalancemodesupported:avcapturewhitebalancemodeautowhitebalance]) {
    [idevice setwhitebalancemode:avcapturewhitebalancemodeautowhitebalance];
  }
  [idevice unlockforconfiguration];
  
  if ([isession canaddinput:ideviceinput]) {
    [isession addinput:ideviceinput];
  }
  if ([isession canaddoutput:istillimageoutput]) {
    [isession addoutput:istillimageoutput];
  }
  if ([isession canaddoutput:ivideooutput]) {
    [isession addoutput:ivideooutput];
  }
  
  //初始化预览图层
  ipreviewlayer = [[avcapturevideopreviewlayer alloc]initwithsession:isession];
  [ipreviewlayer setvideogravity:avlayervideogravityresizeaspectfill];
  ipreviewlayer.frame = cgrectmake(0, 60, [uiscreen mainscreen].bounds.size.width, [uiscreen mainscreen].bounds.size.height-160);
  [self.icameraview.layer addsublayer:ipreviewlayer];
  
  [isession startrunning];
  
  
}

点击按钮拍照:

//拍照
-(void)takepictures{
  avcaptureconnection *connection = [istillimageoutput connectionwithmediatype:avmediatypevideo];
  if (!connection) {
    nslog(@"失败");
    return;
  }
  //设置焦距
  [connection setvideoscaleandcropfactor:1];
  
  [istillimageoutput capturestillimageasynchronouslyfromconnection:connection completionhandler:^(cmsamplebufferref imagedatasamplebuffer, nserror *error) {
    if (imagedatasamplebuffer==null) {
      nslog(@"null");
      return ;
    }
    
    nsdata *data = [avcapturestillimageoutput jpegstillimagensdatarepresentation:imagedatasamplebuffer];
    uiimage *image = [uiimage imagewithdata:data];
    
    
  }];
}

image即为拍照所得图片:

设置session的avcapturesessionpreset属性

-(nsstring *)getsessionpresetfordevice:(avcapturedevice *)device{
  if ([device supportsavcapturesessionpreset:avcapturesessionpreset3840x2160]) {
    return avcapturesessionpreset3840x2160;
  } else if([device supportsavcapturesessionpreset:avcapturesessionpreset1920x1080]){
    return avcapturesessionpreset1920x1080;
  } else if ([device supportsavcapturesessionpreset:avcapturesessionpreset1280x720]){
    return avcapturesessionpreset1280x720;
  } else if ([device supportsavcapturesessionpreset:avcapturesessionpreset640x480]){
    return avcapturesessionpreset640x480;
  } else if ([device supportsavcapturesessionpreset:avcapturesessionpreset352x288]){
    return avcapturesessionpreset352x288;
  } else if ([device supportsavcapturesessionpreset:avcapturesessionpresethigh]){
    return avcapturesessionpresethigh;
  } else if ([device supportsavcapturesessionpreset:avcapturesessionpresetmedium]){
    return avcapturesessionpresetmedium;
  } else{
    return avcapturesessionpresetlow;
  }
}

设置闪光灯:

- (ibaction)iflashbtn:(id)sender {
  
  [idevice lockforconfiguration:nil];
  if (idevice.flashmode == avcaptureflashmodeoff) {
    if ([idevice isflashmodesupported:avcaptureflashmodeon]) {
      [idevice setflashmode:avcaptureflashmodeon];
      
      [self.iflashbtn setbackgroundimage:[uiimage imagenamed:@"flashbtn"] forstate:uicontrolstatenormal];
    }
  } else if (idevice.flashmode == avcaptureflashmodeon){
    if ([idevice isflashmodesupported:avcaptureflashmodeoff]) {
      [idevice setflashmode:avcaptureflashmodeoff];
      
       [self.iflashbtn setbackgroundimage:[uiimage imagenamed:@"flashoffbtn"] forstate:uicontrolstatenormal];
    }
  }
  [idevice unlockforconfiguration];
  
}

切换前置摄像头与后置摄像头:

- (ibaction)ichangebtn:(id)sender {
  
  
  nsarray *array = [avcapturedevice deviceswithmediatype:avmediatypevideo];
  avcapturedevice *newdevice = nil;
  avcapturedeviceinput *newdeviceinput = nil;
  
  catransition *animation = [catransition animation];
  animation.duration = 0.5f;
  animation.timingfunction = [camediatimingfunction functionwithname:kcamediatimingfunctioneaseineaseout];
  animation.type = @"oglflip";
  
  if (idevice.position == avcapturedevicepositionback) {
    animation.subtype = kcatransitionfromleft;
    for (avcapturedevice *device in array) {
      if (device.position == avcapturedevicepositionfront) {
        newdevice = device;
      }
    }
  } else if (idevice.position == avcapturedevicepositionfront){
    animation.subtype = kcatransitionfromright;
    for (avcapturedevice *device in array) {
      if (device.position == avcapturedevicepositionback) {
        newdevice = device;
      }
    }
  }
  
  newdeviceinput = [avcapturedeviceinput deviceinputwithdevice:newdevice error:nil];
  [ipreviewlayer addanimation:animation forkey:nil];
  if (newdeviceinput!=nil) {
    [isession beginconfiguration];
    [isession removeinput:ideviceinput];
     isession.sessionpreset = [self getsessionpresetfordevice:newdevice];
    if ([isession canaddinput:newdeviceinput]) {
      [isession addinput:newdeviceinput];
      ideviceinput = newdeviceinput;
      idevice = newdevice;
    } else {
      [isession addinput:ideviceinput];
    }
    [isession commitconfiguration];
  }
  
  
}

点击屏幕对焦:

//点击屏幕对焦
-(void)focustap:(uigesturerecognizer *)tap{
  cgpoint tappoint = [tap locationinview:self.view];
  
  
  float y = tappoint.y;
  if (y<60 || y>([uiscreen mainscreen].bounds.size.height-100)) {
    return;
  }
  
  [idevice lockforconfiguration:nil];
  if ([idevice isfocusmodesupported:avcapturefocusmodeautofocus]) {
    [idevice setfocuspointofinterest:cgpointmake(tappoint.x/self.view.frame.origin.x, tappoint.y/self.view.frame.origin.y)];
    [idevice setfocusmode:avcapturefocusmodeautofocus];
  }
  [idevice unlockforconfiguration];
  
  self.ifocusimgview.center = tappoint;
  self.ifocusimgview.hidden = no;
  [uiview animatewithduration:0.3 animations:^{
    self.ifocusimgview.transform = cgaffinetransformmakescale(1.25, 1.25);
  }completion:^(bool finished) {
    [uiview animatewithduration:0.5 animations:^{
      self.ifocusimgview.transform = cgaffinetransformidentity;
    } completion:^(bool finished) {
      self.ifocusimgview.hidden = yes;
    }];
  }];
}

关于视频录制可以在demo中查看。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。