iOS拍照定制之AVCaptureVideoDataOutput
问题
领导看了前面做的拍照,问了句"哪来的声音",
"系统的,自带的,你看系统的拍照也有声音"
"有办法能去掉吗?挺糟心的"
"我试试"
思路
路漫漫其修远兮,吾在度娘+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的更多相关文章
- iOS拍照定制之AVCapturePhotoOutput
问题 领导安排任务,写个拍照功能,界面跟系统拍照有点出入 拍完照片,底部显示已拍照片,有个拍照上限[在此不论] 点击已拍照片,可以预览.放大缩小查看 思路 系统拍照肯定不行了,只能定制,没提是否拍照禁 ...
- iOS开发-定制多样式二维码
iOS开发-定制多样式二维码 二维码/条形码是按照某种特定的几何图形按一定规律在平台(一维/二维方向上)分布的黑白相间的图形纪录符号信息.使用若干个与二进制对应的几何形体来表示文字数值信息. 最常 ...
- 图片上传前 压缩,base64图片压缩 Exif.js处理ios拍照倒置等问题
曾写过在前端把图片按比例压缩不失真上传服务器的前端和后台,可惜没有及时做总结保留代码,只记得js利用了base64位压缩和Exif.js进行图片处理,还有其中让我头疼的ios拍照上传后会倒置等诸多问题 ...
- iOS 拍照中加入GPS和具体地理位置
最近有一个需求,要求用手机拍个照片,并切需要拍摄时间,拍摄gps,拍摄具体街道信息. 首先要感谢PhotoGPSdemo的作者,你可以到这里下载demo http://www.cocoachina.c ...
- iOS拍照图片旋转的问题
很久之前,遇到了这种情况,iOS某端拍照上传到服务器,其他iOS端从服务器下载该照片展示,发现图片逆时针旋转了90度.当时百度了一下,找到一段代码修正image方向,问题解决了,但没有深入理解底层原理 ...
- iOS拍照之系统拍照
拍照在App中使用频次高,入门级别直接调用系统拍照 思路: 系统拍照使用UIImagePickerController 1.设置下plist,否则没权限,报错 2.判断摄像头,获取权限,否则弹出界面黑 ...
- iOS拍照上传后,在web端显示旋转 Swift+OC版解决方案
问题描述: 手机头像上传,遇到一个怪现象,就是拍照上传时,手机端显示头像正常,但在web端查看会有一个左旋90度的问题. 并且照片竖怕才会有此问题,横拍不存在. 原因分析: 手机拍照时,用相机拍摄出来 ...
- iOS 7定制UIPageControl遇到的问题
转自snorlax's blog 先说下ios7之前 那些点点的实现非常简单 就是UIPageControl.subviews 就是一个个点的UIImageView 所以只需简单的替换掉就好了代码如下 ...
- iOS自定制tabbar与系统的tabbar冲突,造成第一次点击各个item图片更换选中,第二次选中部分item图片不改变
可以选择是使用自定制的还是系统的,如果使用自定制的,就使用以下方法即可隐藏系统的uitabbarButton,从而使item恢复正确 //隐藏UITabBarButton -(void)viewWil ...
随机推荐
- linux上 用户间发送消息 通信
联想:scp命令 1.使用write命令,向指定用户发送信息: 用户可以使用write命令给其他在线用户发送消息.格式: $ write zhangsan hello worl ...
- sudo 配置
在ubuntu中由于禁用了root用户,默认情况下会把安装系统时建立的用户添加到sudoers中. 但在redhat和centos中并没有把任何root用户之外的用户默认的添加到sudoers之中.这 ...
- Git实现1个项目2个地址1次推送
Git实现1个项目2个地址1次推送 考虑到不需要pull操作,因此本方法适用于个人项目分别在两个平台或地址进行部署 给origin 增加一个可以push的地址 git remote set-url - ...
- Flink-v1.12官方网站翻译-P029-User-Defined Functions
用户自定义函数 大多数操作都需要用户定义的函数.本节列出了如何指定这些函数的不同方法.我们还涵盖了累加器,它可以用来深入了解您的Flink应用. Lambda函数 在前面的例子中已经看到,所有的操作都 ...
- Pytest(17)运行未提交的git(pytest-picked)
前言 我们每天写完自动化用例后都会提交到 git 仓库,随着用例的增多,为了保证仓库代码的干净,当有用例新增的时候,我们希望只运行新增的未提交 git 仓库的用例.pytest-picked 插件可以 ...
- Pytest(11)allure报告
前言 allure是一个report框架,支持java的Junit/testng等框架,当然也可以支持python的pytest框架,也可以集成到Jenkins上展示高大上的报告界面. mac环境: ...
- 牛客挑战赛33 C 艾伦的立体机动装置(几何)
思路: 我们需要枚举展开多少条边 然后把上底面的点放到和下底面一个平面 然后算两点之间的距离 注意判断直线与线段是否有交点 #include <bits/stdc++.h> using n ...
- Codeforces Round #635 (Div. 2)
Contest Info Practice Link Solved A B C D E F 4/6 O O Ø Ø O 在比赛中通过 Ø 赛后通过 ! 尝试了但是失败了 - 没有尝试 Sol ...
- P2801 教主的魔法 (分块)
题目传送 长度为\(n(n\le 1000000)\)的数组,\(q(q\le 3000)\) 次操作.修改操作即将某个区间的值增加某个不大于1000的值,查询操作即查询某个区间比C大于等于的数有多少 ...
- Docker文件挂载总结
Docker容器启动的时候,如果要挂载宿主机的一个目录,可以用-v参数指定. 譬如我要启动一个centos容器,宿主机的/test目录挂载到容器的/soft目录,可通过以下方式指定: # docker ...