Есть ли способ сделать снимок в коде на iPhone без прохождения контроля Apple? Я видел множество приложений, которые делают это, но я не уверен, какой API-вызов использовать.
Сделайте снимок на iPhone без отображения элементов управления
Ответ 1
Да, есть два способа сделать это. Один из них, доступный в iOS 3.0+, должен использовать класс UIImagePickerController
, установив для свойства showsCameraControls
значение НЕТ и установив свойство cameraOverlayView
в собственные пользовательские элементы управления. Два, доступные в iOS 4.0+, должны конфигурировать AVCaptureSession
, предоставляя ему AVCaptureDeviceInput
с помощью соответствующего устройства камеры и AVCaptureStillImageOutput
. Первый подход намного проще и работает на большей версии iOS, но второй подход дает вам гораздо больший контроль над разрешением фотографий и параметрами файлов.
Ответ 2
РЕДАКТИРОВАТЬ: Как было предложено в комментариях ниже, я теперь прямо показал, как AVCaptureSession необходимо объявить и инициализировать. Похоже, что некоторые из них неправильно выполняли инициализацию или объявляли AVCaptureSession в качестве локальной переменной в методе. Это не сработает.
Следующий код позволяет делать снимок с помощью AVCaptureSession без ввода пользователем:
// Get all cameras in the application and find the frontal camera.
AVCaptureDevice *frontalCamera;
NSArray *allCameras = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
// Find the frontal camera.
for ( int i = 0; i < allCameras.count; i++ ) {
AVCaptureDevice *camera = [allCameras objectAtIndex:i];
if ( camera.position == AVCaptureDevicePositionFront ) {
frontalCamera = camera;
}
}
// If we did not find the camera then do not take picture.
if ( frontalCamera != nil ) {
// Start the process of getting a picture.
session = [[AVCaptureSession alloc] init];
// Setup instance of input with frontal camera and add to session.
NSError *error;
AVCaptureDeviceInput *input =
[AVCaptureDeviceInput deviceInputWithDevice:frontalCamera error:&error];
if ( !error && [session canAddInput:input] ) {
// Add frontal camera to this session.
[session addInput:input];
// We need to capture still image.
AVCaptureStillImageOutput *output = [[AVCaptureStillImageOutput alloc] init];
// Captured image. settings.
[output setOutputSettings:
[[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG,AVVideoCodecKey,nil]];
if ( [session canAddOutput:output] ) {
[session addOutput:output];
AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection *connection in output.connections) {
for (AVCaptureInputPort *port in [connection inputPorts]) {
if ([[port mediaType] isEqual:AVMediaTypeVideo] ) {
videoConnection = connection;
break;
}
}
if (videoConnection) { break; }
}
// Finally take the picture
if ( videoConnection ) {
[session startRunning];
[output captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
if (imageDataSampleBuffer != NULL) {
NSData *imageData = [AVCaptureStillImageOutput
jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
UIImage *photo = [[UIImage alloc] initWithData:imageData];
}
}];
}
}
}
}
переменная сеанса имеет тип AVCaptureSession и объявлена в .h файле класса (либо как свойство, либо как частный член класса):
AVCaptureSession *session;
Затем он должен быть инициализирован где-то, например, в методе init:
session = [[AVCaptureSession alloc] init]