iOS自定义相机Demo

//  Created by David_Tian on 14-9-24.
//  Copyright (c) 2014年 All rights reserved.
//  未做适配,有兴趣的童鞋可以扩展

#import "cameraViewController.h"
#import <AVFoundation/AVFoundation.h>
#import <ImageIO/ImageIO.h>
#import <QuartzCore/QuartzCore.h>

typedef enum{
    isFrontCamera = 0,
    isBackCamera
} cameraType;

typedef enum{
    AutoFlash = 0,
    CloseFlash,
    OpenFlash
} flashModel;

@interface cameraViewController ()
< AVCaptureAudioDataOutputSampleBufferDelegate, UIImagePickerControllerDelegate >
{
    UIImage *_photo;
    BOOL _isFontCamera;
}

@property (strong, nonatomic) AVCaptureSession           *session;       // 捕获会话
@property (nonatomic, strong) AVCaptureStillImageOutput  *captureOutput; // 输出设备
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer;  // 取景器 

@end

@implementation cameraViewController

- (AVCaptureSession *)session
{
    if (_session == nil) {
        _session = [[AVCaptureSession alloc] init];
    }
    return _session;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor grayColor];
    UIButton *btnCam = [[UIButton alloc]initWithFrame:CGRectMake(20, 44, 80, 30)];
    [btnCam setTitle:@"拍照" forState:UIControlStateNormal];
    [btnCam setTitle:@"重照" forState:UIControlStateSelected];//重拍没做
    [btnCam setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [btnCam addTarget:self action:@selector(capture) forControlEvents:UIControlEventTouchUpInside];
    [btnCam setBackgroundColor:[UIColor whiteColor]];
    [self.view addSubview:btnCam];

    UIButton *btnSelectCam = [[UIButton alloc]initWithFrame:CGRectMake(110, 44, 80, 30)];
    [btnSelectCam setTitle:@"后置相机" forState:UIControlStateNormal];
    [btnSelectCam setTitle:@"前置相机" forState:UIControlStateSelected];
    [btnSelectCam setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [btnSelectCam addTarget:self action:@selector(switchCamera:) forControlEvents:UIControlEventTouchUpInside];
    [btnSelectCam setBackgroundColor:[UIColor whiteColor]];
    [self.view addSubview:btnSelectCam];  

    UIButton *btnFlash = [[UIButton alloc]initWithFrame:CGRectMake(200, 44, 80, 30)];
    [btnFlash setTitle:@"闪光灯" forState:UIControlStateNormal];
    [btnFlash setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [btnFlash addTarget:self action:@selector(switchFlashMode:) forControlEvents:UIControlEventTouchUpInside];
    [btnFlash setBackgroundColor:[UIColor whiteColor]];
    [self.view addSubview:btnFlash];

    [self switchCamera:nil];
}
#pragma mark - action
// 拍照
- (void)capture
{
    if (![self.session isRunning]) {
        [self getPhoto];
    }else{
        [_session stopRunning];
    }
}
// 切换摄像头
- (void)switchCamera:(UIButton *)sender
{
    [self.session stopRunning];
    [_previewLayer removeFromSuperlayer];
    sender.selected = !sender.selected;
    _isFontCamera = !_isFontCamera;
    [self setupCamera];
}
// 获取图片
- (void)getPhoto
{
    AVCaptureConnection *videoConnection = nil;
    for (AVCaptureConnection *connection in _captureOutput.connections) {
        for (AVCaptureInputPort *port in [connection inputPorts]) {
            if ([[port mediaType] isEqual:AVMediaTypeVideo] ) {
                videoConnection = connection;
                break;
            }
        }
        if (videoConnection) {
            break;
        }
    }
    [_captureOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:^(CMSampleBufferRef imageSampleBuffer, NSError *error)
    {
        CFDictionaryRef exifAttachments = CMGetAttachment(imageSampleBuffer, kCGImagePropertyExifDictionary, nil);
        if (exifAttachments) {
            // Do something with the attachments.
        }
        // 获取图片数据
        NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
        UIImage *t_image = [[UIImage alloc] initWithData:imageData];
        _photo = [[UIImage alloc]initWithCGImage:t_image.CGImage scale:1.5 orientation:UIImageOrientationRight];
        UIImageView *imageView = [[UIImageView alloc]initWithFrame:_previewLayer.frame];
        [_previewLayer removeFromSuperlayer];
        imageView.image = _photo;
        imageView.contentMode = UIViewContentModeScaleAspectFill;
        imageView.clipsToBounds = YES;
        [self.view addSubview:imageView];
    }];
}

// 切换闪光灯模式
- (void)switchFlashMode:(UIButton*)sender {
    Class captureDeviceClass = NSClassFromString(@"AVCaptureDevice");
    if (!captureDeviceClass) {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示信息" message:@"您的设备没有拍照功能" delegate:nil cancelButtonTitle:NSLocalizedString(@"Sure", nil) otherButtonTitles: nil];
        [alert show];
        return;
    }
    NSString *imgName = @"";
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    [device lockForConfiguration:nil];
    if ([device hasFlash]) {
        if (device.flashMode == AVCaptureFlashModeOff) {
            device.flashMode = AVCaptureFlashModeOn;
            imgName = @"";
        } else if (device.flashMode == AVCaptureFlashModeOn) {
            device.flashMode = AVCaptureFlashModeAuto;
            imgName = @"";
        } else if (device.flashMode == AVCaptureFlashModeAuto) {
            device.flashMode = AVCaptureFlashModeOff;
            imgName = @"";
        }
        if (sender) {
            [sender setImage:[UIImage imageNamed:imgName] forState:UIControlStateNormal];
        }
    } else {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示信息" message:@"您的设备没有闪光灯功能" delegate:nil cancelButtonTitle:@"ok" otherButtonTitles: nil];
        [alert show];
    }
    [device unlockForConfiguration];
}

// 初始化相机

- (void)setupCamera
{
    AVCaptureDevice *captureDevice = [self getVideoInputCamera:(_isFontCamera ? isFrontCamera : isBackCamera)];
    AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:nil];
    if ([self.session canAddInput:deviceInput]){
        [_session addInput:deviceInput];
    }

    // 预览视图(取景器)
    _previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session];
    [_previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];

    CALayer *preLayer = [[self view] layer];
    [preLayer setMasksToBounds:YES];
    [_previewLayer setFrame:CGRectMake(10, 100, 300, 300)];
    [preLayer insertSublayer:_previewLayer atIndex:0];
    [_session startRunning];

    // 创建一个输出设备,并将它添加到会话
    _captureOutput = [[AVCaptureStillImageOutput alloc] init];
    NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG,AVVideoCodecKey,nil];
    _captureOutput.outputSettings = outputSettings;
    [_session addOutput:_captureOutput];
}

#pragma mark VideoCapture
- (AVCaptureDevice *)getVideoInputCamera:(cameraType )cameraType
{
    //获取(后置/前置)摄像头设备
    NSArray *cameras = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
    for (AVCaptureDevice *device in cameras){
        switch (cameraType) {
            case isFrontCamera:
                if (device.position == AVCaptureDevicePositionFront)
                    return device;
                break;
            case isBackCamera:
                if (device.position == AVCaptureDevicePositionBack)
                    return device;
                break;
            default:
                break;
        }
    }
    return [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
}

@end
时间: 2024-12-05 23:29:39

iOS自定义相机Demo的相关文章

Android 自定义相机Demo源码

Github源码:https://github.com/LinJZong/AndroidProject.git 模仿360相机,图片资源来源于360相机,仅供学习使用.截图如下: 目前完成了拍照.保存.图片压缩.触摸聚焦.拍照成功附带动画效果.闪光灯切换.手势缩放等功能,功能持续更新中. 最近更新的较频繁,就不放csdn了,等功能全做完了再传csdn.介绍下目前主要几个功能类凑够200字. public class CameraView extends SurfaceView implement

iOS 自定义相机,带水印!

// //  HSZJLCameraViewC.m //  HSZJLCamera // //  Created by 紫霞大仙 on 16/1/16. //  Copyright © 2016年 Hipal. All rights reserved. // #import "HSZJLCameraViewC.h" #import <AVFoundation/AVFoundation.h> #import "HSSaveViewController.h"

【Android】自定义相机的实现(支持连续拍照、前后摄像头切换、连续对焦)

~转载请注明http://blog.csdn.net/u013015161/article/details/46921257 介绍 这几天,写了一个自定义照相机的demo,支持连续拍照和摄像头切换.由于自己以前没接触过相关的编程,也算是一个学习的过程,在这里做一下记录,同时也分享出来,并附上源码和工程. 效果如图: 左上角switch切换摄像头,右边snap按钮进行拍照. 一般流程 Android进行拍照,需要调用摄像头类android.hardware.Camera.而要进行预览,则需要用an

iOS开发笔记17:自定义相机拍照

之前用AVFoundation自定义相机做了拍照与视频相关的东西,为什么要自定义呢?主要是提供更个性化的交互设计,符合app主题,对于视频来说,也便于提供更多丰富有趣的功能.前段时间整理了下拍照部分的功能,主要分为以下五个部分 1.初始化,建立会话,获取摄像头 使用AVCaptureSessionPresetPhoto模式,输出的图片分辨率与系统相机输出的分辨率保持一致 添加后置摄像头与图片输出(默认采用后置摄像头拍摄) 2.嵌入实时预览层 获取实时预览画面,添加手势,初始化时默认在画面中心点对

Android调用系统相机、自定义相机、处理大图片

Android调用系统相机和自定义相机实例 本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显示出来,该例子也会涉及到Android加载大图片时候的处理(避免OOM),还有简要提一下有些人SurfaceView出现黑屏的原因. Android应用拍照的两种方式,下面为两种形式的Demo展示出来的效果.    知识点: 一.调用系统自带的相机应用 二.自定义我们自己的拍照界面 三.关于计算机解析图片原理(如何正确加载图片到Android应用中) 所需

iOS 自定义页面的切换动画与交互动画

在iOS7之前,开发者为了寻求自定义Navigation Controller的Push/Pop动画,只能受限于子类化一个UINavigationController,或是用自定义的动画去覆盖它.但是随着iOS7的到来,Apple针对开发者推出了新的工具,以更灵活地方式管理UIViewController切换. 自定义导航栏的Push/Pop动画 为了在基于UINavigationController下做自定义的动画切换,先建立一个简单的工程,这个工程的rootViewController是一个

android开发——自定义相机开发总结

最近这段时间我一直在开发自定义相机,谷歌了些网上的demo,发现有很多各种各样的问题.最终还是从API的camera类开始学习,进行改进.下面对之前的实现进行一些总结. 官方camera API: http://developer.android.com/guide/topics/media/camera.html 中文翻译: http://www.cnblogs.com/over140/archive/2011/11/16/2251344.html 自定义相机大致实现流程: 预览Camera这

iOS自定义转场动画实战讲解

iOS自定义转场动画实战讲解 转场动画这事,说简单也简单,可以通过presentViewController:animated:completion:和dismissViewControllerAnimated:completion:这一组函数以模态视图的方式展现.隐藏视图.如果用到了navigationController,还可以调用pushViewController:animated:和popViewController这一组函数将新的视图控制器压栈.弹栈. 下图中所有转场动画都是自定义的

AVFoundation的自定义相机

最近由于工作项目的功能需求,需要用到AVFoundation来自定义相机的功能.所以花了点时间去研究了一下. 在网上可以找到很多实用AVFoundation的自定义相机自定义相机的博文,虽然功能的确是完成了,但是距离我的目标还是有不少的差距的. 首先声明,预览的照片是正方形的,拍摄结果最后得到的图片也是正方形的,再好多的博文上我都没有找到该怎么设置才可以得到正方形的图片. 我是首先拍一张照片,然后在使用图片裁剪的方式得到的正方行图片.好了,接下来就让我们开始吧. 首先要了解这几个类的用处 /**