• 问题

    领导看了前面做的拍照,问了句"哪来的声音",

    "系统的,自带的,你看系统的拍照也有声音"

    "有办法能去掉吗?挺糟心的"

    "我试试"

  • 思路

    路漫漫其修远兮,吾在度娘+SDK中求索

    拍砖AVCaptureVideoDataOutput, 代理方法中将CMSampleBufferRef转成UIImage

  • 上码

    • session设置不提

    • layer设置可参考上篇 [iOS拍照定制之AVCapturePhotoOutput] 以及 上上篇[iOS写在定制相机之前]

    • 获取摄像头、取到设备输入添加到session、初始化videoOutput添加入session

    AVCaptureDevice *device = [self cameraDevice];
    if (!device) {
    NSLog(@"取得后置摄像头出问题");
    return;;
    } NSError *error = nil;
    self.videoInput = [[AVCaptureDeviceInput alloc] initWithDevice:device error:nil]; // 设备添加到会话中
    if ([self.captureSession canAddInput:self.videoInput]) {
    [self.captureSession addInput:self.videoInput];
    } [self.videoOutput setSampleBufferDelegate:self queue:self.videoQueue];
    if ([self.captureSession canAddOutput:self.videoOutput]) {
    [self.captureSession addOutput:self.videoOutput];
    } // 懒加载
    - (AVCaptureVideoDataOutput *)videoOutput {
    if (!_videoOutput) {
    _videoOutput = [[AVCaptureVideoDataOutput alloc] init];
    _videoOutput.alwaysDiscardsLateVideoFrames = YES;
    _videoOutput.videoSettings = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA]
    forKey:(id)kCVPixelBufferPixelFormatTypeKey];
    }
    return _videoOutput;
    } - (dispatch_queue_t)videoQueue {
    if (!_videoQueue) {
    _videoQueue = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);
    }
    return _videoQueue;
    }
    • 代理AVCaptureVideoDataOutputSampleBufferDelegate
    - (void)captureOutput:(AVCaptureOutput *)output didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
    @autoreleasepool {
    if (connection == [self.videoOutput connectionWithMediaType:AVMediaTypeVideo]) { // 视频
    @synchronized (self) {
    UIImage *image = [self bufferToImage:sampleBuffer rect:self.scanView.scanRect];
    self.uploadImg = image;
    }
    }
    }
    }
    • CMSampleBufferRef转成UIImage, 该方法有所调整,截图整张图中的某一部分,按需设置。具体获取指定区域图片需自己调整
    - (UIImage *)bufferToImage:(CMSampleBufferRef)sampleBuffer rect:(CGRect)rect {
    // Get a CMSampleBuffer's Core Video image buffer for the media data
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
    // Lock the base address of the pixel buffer
    CVPixelBufferLockBaseAddress(imageBuffer, 0); // Get the number of bytes per row for the pixel buffer
    void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer); // Get the number of bytes per row for the pixel buffer
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
    // Get the pixel buffer width and height
    size_t width = CVPixelBufferGetWidth(imageBuffer);
    size_t height = CVPixelBufferGetHeight(imageBuffer); // Create a device-dependent RGB color space
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); // Create a bitmap graphics context with the sample buffer data
    CGContextRef context = CGBitmapContextCreate(baseAddress, width, height, 8,
    bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
    // Create a Quartz image from the pixel data in the bitmap graphics context
    CGImageRef quartzImage = CGBitmapContextCreateImage(context);
    // Unlock the pixel buffer
    CVPixelBufferUnlockBaseAddress(imageBuffer,0); // Free up the context and color space
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace); // 获取指定区域图片
    CGRect dRect;
    CGSize msize = UIScreen.mainScreen.bounds.size;
    msize.height = msize.height - 150;
    CGFloat x = width * rect.origin.x / msize.width;
    CGFloat y = height * rect.origin.y / msize.height;
    CGFloat w = width * rect.size.width / msize.width;
    CGFloat h = height * rect.size.height / msize.height;
    dRect = CGRectMake(x, y, w, h); CGImageRef partRef = CGImageCreateWithImageInRect(quartzImage, dRect); // Create an image object from the Quartz image
    UIImage *image = [UIImage imageWithCGImage:partRef]; // Release the Quartz image
    CGImageRelease(partRef);
    CGImageRelease(quartzImage); return image;
    }
  • 图有了,收工。怎么用图,业务该干活了

iOS拍照定制之AVCaptureVideoDataOutput的更多相关文章

  1. iOS拍照定制之AVCapturePhotoOutput

    问题 领导安排任务,写个拍照功能,界面跟系统拍照有点出入 拍完照片,底部显示已拍照片,有个拍照上限[在此不论] 点击已拍照片,可以预览.放大缩小查看 思路 系统拍照肯定不行了,只能定制,没提是否拍照禁 ...

  2. iOS开发-定制多样式二维码

    iOS开发-定制多样式二维码   二维码/条形码是按照某种特定的几何图形按一定规律在平台(一维/二维方向上)分布的黑白相间的图形纪录符号信息.使用若干个与二进制对应的几何形体来表示文字数值信息. 最常 ...

  3. 图片上传前 压缩,base64图片压缩 Exif.js处理ios拍照倒置等问题

    曾写过在前端把图片按比例压缩不失真上传服务器的前端和后台,可惜没有及时做总结保留代码,只记得js利用了base64位压缩和Exif.js进行图片处理,还有其中让我头疼的ios拍照上传后会倒置等诸多问题 ...

  4. iOS 拍照中加入GPS和具体地理位置

    最近有一个需求,要求用手机拍个照片,并切需要拍摄时间,拍摄gps,拍摄具体街道信息. 首先要感谢PhotoGPSdemo的作者,你可以到这里下载demo http://www.cocoachina.c ...

  5. iOS拍照图片旋转的问题

    很久之前,遇到了这种情况,iOS某端拍照上传到服务器,其他iOS端从服务器下载该照片展示,发现图片逆时针旋转了90度.当时百度了一下,找到一段代码修正image方向,问题解决了,但没有深入理解底层原理 ...

  6. iOS拍照之系统拍照

    拍照在App中使用频次高,入门级别直接调用系统拍照 思路: 系统拍照使用UIImagePickerController 1.设置下plist,否则没权限,报错 2.判断摄像头,获取权限,否则弹出界面黑 ...

  7. iOS拍照上传后,在web端显示旋转 Swift+OC版解决方案

    问题描述: 手机头像上传,遇到一个怪现象,就是拍照上传时,手机端显示头像正常,但在web端查看会有一个左旋90度的问题. 并且照片竖怕才会有此问题,横拍不存在. 原因分析: 手机拍照时,用相机拍摄出来 ...

  8. iOS 7定制UIPageControl遇到的问题

    转自snorlax's blog 先说下ios7之前 那些点点的实现非常简单 就是UIPageControl.subviews 就是一个个点的UIImageView 所以只需简单的替换掉就好了代码如下 ...

  9. iOS自定制tabbar与系统的tabbar冲突,造成第一次点击各个item图片更换选中,第二次选中部分item图片不改变

    可以选择是使用自定制的还是系统的,如果使用自定制的,就使用以下方法即可隐藏系统的uitabbarButton,从而使item恢复正确 //隐藏UITabBarButton -(void)viewWil ...

随机推荐

  1. LCA算法——倍增

    概况 LCA(Lowest Common Ancestors),即最近公共祖先,是指在有根树中,找出某两个结点u和v最近的公共祖先. 实现过程 预处理:通过dfs遍历,记录每个节点到根节点的距离dis ...

  2. BZOJ1396 识别子串【SAM+SegmentTree】

    BZOJ1396 识别子串 给定一个串\(s\),对于串中的每个位置,输出经过这个位置且只在\(s\)中出现一次的子串的最短长度 朴素的想法是,我们要找到那些只出现一次的子串,之后遍历每个串,把串所覆 ...

  3. hdu5432Rikka with Array (数位dp+十进制转化为二进制)

    Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, so he ...

  4. hdu5375 Gray code

    Problem Description The reflected binary code, also known as Gray code after Frank Gray, is a binary ...

  5. Codeforces Round #643 (Div. 2) E. Restorer Distance (贪心,三分)

    题意:给你\(n\)个数,每次可以使某个数++,--,或使某个数--另一个++,分别消耗\(a,r,m\).求使所有数相同最少的消耗. 题解:因为答案不是单调的,所以不能二分,但不难发现,答案只有一个 ...

  6. JavaScript——三

    任务: 其中的"options = options || {}"就代表如果options是一个真的对象,就使用它,否则就给他默认值 在Node函数中: 函数中的this指向wind ...

  7. Educational Codeforces Round 94 (Rated for Div. 2) A. String Similarity (构造水题)

    题意:给你一个长度为\(2*n-1\)的字符串\(s\),让你构造一个长度为\(n\)的字符串,使得构造的字符串中有相同位置的字符等于\(s[1..n],s[2..n+1],...,s[n,2n-1] ...

  8. 大规模数据爬取 -- Python

    Python书写爬虫,目的是爬取所有的个人商家商品信息及详情,并进行数据归类分析 整个工作流程图: 第一步:采用自动化的方式从前台页面获取所有的频道 from bs4 import Beautiful ...

  9. MySQL 字符集及校验规则

    字符集 Mysql 的字符集有4个级别的默认设置:服务器级,数据库级,表级和字段级,客户端交互时,也可以指定字符集 # 字符集:是一个系统支持的所有抽象字符的集合.字符是各种文字和符号的总称,包括各国 ...

  10. Crontab 简单实现树莓派语音闹钟

    树莓派实验室按:这是来自 hyhmnn 的投稿.是时候关掉你的手机闹铃了,用树莓派外接一个音箱就可以 Make 一款科技感和实用性兼备的"AI 闹钟".这里用到了 Linux 的计 ...