[英]Capture a still image on iOS7 through a console app
我试图通过控制台在越狱的iPhone上捕获静止图像。
免责声明:我是一个Objective-C新手-大部分代码来自: AVCaptureStillImageOutput从不调用完成处理程序
我只想知道它是否可以在终端上工作。
我已经尝试过各种关于SO的示例,但似乎都没有用。 我的问题是-可能吗? 还是Apple由于某些原因将其锁定(可能不允许通过终端访问相机等)。
这是我当前的相机。
#import <Foundation/Foundation.h>
#import <CoreVideo/CoreVideo.h>
#import <CoreMedia/CoreMedia.h>
#import <AVFoundation/AVFoundation.h>
#import <ImageIO/CGImageProperties.h>
#import <stdio.h>
#import <UIKit/UIKit.h>
@interface Camera : NSObject {
}
@property (readwrite, retain) AVCaptureStillImageOutput *stillImageOutput;
- (AVCaptureDevice *)frontFacingCameraIfAvailable;
- (void)setupCaptureSession;
- (void)captureNow;
@end
@implementation Camera
@synthesize stillImageOutput;
-(AVCaptureDevice *) frontFacingCameraIfAvailable{
NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
AVCaptureDevice *captureDevice = nil;
for (AVCaptureDevice *device in videoDevices){
if (device.position == AVCaptureDevicePositionFront){
captureDevice = device;
break;
}
}
// couldn't find one on the front, so just get the default video device.
if (!captureDevice){
captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
}
return captureDevice;
}
-(void) setupCaptureSession {
AVCaptureSession *session = [[AVCaptureSession alloc] init];
session.sessionPreset = AVCaptureSessionPresetMedium;
AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
//[self.view.layer addSublayer:captureVideoPreviewLayer];
NSError *error = nil;
AVCaptureDevice *device = [self frontFacingCameraIfAvailable];
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if (!input) {
// Handle the error appropriately.
NSLog(@"ERROR: trying to open camera: %@", error);
}
[session addInput:input];
self.stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys: AVVideoCodecJPEG, AVVideoCodecKey, nil];
[self.stillImageOutput setOutputSettings:outputSettings];
[session addOutput:self.stillImageOutput];
[session startRunning];
}
-(void) captureNow {
AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection *connection in self.stillImageOutput.connections) {
for (AVCaptureInputPort *port in [connection inputPorts]) {
if ([[port mediaType] isEqual:AVMediaTypeVideo] ) {
videoConnection = connection;
break;
}
}
if (videoConnection) { break; }
}
NSLog(@"about to request a capture from: %@", self.stillImageOutput);
[self.stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error) {
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
UIImage *image = [[UIImage alloc] initWithData:imageData];
NSLog(@"image captured: %@", [imageData bytes]);
}];
}
@end
int main(int argc, const char *argv[]) {
Camera *camera = [[Camera alloc] init];
[camera setupCaptureSession];
[camera captureNow];
}
这是我的Makefile:
XCODE_BASE=/Applications/Xcode.app/Contents
IPHONEOS=$(XCODE_BASE)/Developer/Platforms/iPhoneOS.platform
SDK=$(IPHONEOS)/Developer/SDKs/iPhoneOS7.1.sdk
FRAMEWORKS=$(SDK)/System/Library/Frameworks/
INCLUDES=$(SDK)/usr/include
camera:
clang -mios-version-min=7.0 \
-isysroot $(SDK) \
-arch armv7 \
camera.m \
-lobjc \
-framework Foundation -framework AVFoundation -framework CoreVideo -framework CoreMedia -framework CoreGraphics -framework CoreImage -framework UIKit -framework ImageIO \
-o camera
将相机二进制文件复制到iPhone:
scp camera root@10.1.1.32:/var/root/camera
root@10.1.1.32's password:
camera 100% 51KB 51.0KB/s 00:00
iPhone运行该应用程序的结果:
iPhone:~ root# ./camera
2014-03-21 15:17:55.550 camera[9483:507] about to request a capture from: <AVCaptureStillImageOutput: 0x14e2b940>
如您所见,正确设置了AVCaptureSession,找到并设置了前置摄像头,正确设置了AVCaptureConnection。 但是captureStillImageAsynchronouslyFromConnection:completionHandler:永远不会被调用。
这有可能吗? 难道我做错了什么?
编辑:我已经修改了captureNow使其在线程上休眠,直到completedHandler完成并且应用程序在启动后一直等待。
-(void) captureNow {
AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection *connection in self.stillImageOutput.connections) {
for (AVCaptureInputPort *port in [connection inputPorts]) {
if ([[port mediaType] isEqual:AVMediaTypeVideo] ) {
videoConnection = connection;
break;
}
}
if (videoConnection) { break; }
}
__block BOOL done = NO;
NSLog(@"about to request a capture from: %@", self.stillImageOutput);
[self.stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error) {
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
UIImage *image = [[UIImage alloc] initWithData:imageData];
NSLog(@"image captured");
done = YES;
}];
while (!done) {
[NSThread sleepForTimeInterval:1.0];
}
}
您的应用在捕获照片之前退出。 需要将completionBlock arg添加到-captureNow,并且在主要实现中应如下所示:
__block BOOL done = NO;
[camera captureWithCompletionBlock:^(UIImage* image)
{
done = YES;
}];
while (!done)
{
[[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
}
我的意思是这样的-
- (void)captureWithCompletionBlock:(void(^)(UIImage* image))block {
AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection *connection in self.stillImageOutput.connections) {
for (AVCaptureInputPort *port in [connection inputPorts]) {
if ([[port mediaType] isEqual:AVMediaTypeVideo] ) {
videoConnection = connection;
break;
}
}
if (videoConnection) { break; }
}
NSLog(@"about to request a capture from: %@", self.stillImageOutput);
[self.stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error) {
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
UIImage *image = [[UIImage alloc] initWithData:imageData];
NSLog(@"image captured: %@", [imageData bytes]);
block(image);
}];
}
另外,您需要保留AVCaptureSession,只需将其添加为属性即可。
@property (nonatomic,strong) AVCaptureSession* session;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.