IOS自动抓图
Posted
技术标签:
【中文标题】IOS自动抓图【英文标题】:Capture picture automatically in IOS 【发布时间】:2013-10-21 21:31:18 【问题描述】:我的要求是编写一个示例 ios 应用程序,该应用程序将自动捕获相机图片。使用提供的各种 S.O 链接,我确实实现了以下代码 -
我的 CameraViewController.h 类定义如下:
@interface CameraViewController : UIViewController <UIImagePickerControllerDelegate, UINavigationControllerDelegate>
@property (strong, nonatomic) IBOutlet UIImageView *ImageView;
@end
CameraViewController.m 代码如下:
-(void)viewDidAppear:(BOOL)animated
NSLog(@"Setting the background now");
UIImagePickerController *picker = [[UIImagePickerController alloc] init];picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
picker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
picker.cameraDevice = UIImagePickerControllerCameraDeviceRear;
picker.showsCameraControls = NO;
picker.navigationBarHidden = NO;
picker.toolbarHidden = NO;
[self presentViewController:picker animated:YES completion:NULL];
NSLog(@"Taking the picture now");
[picker takePicture];
-(void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
NSLog(@"Entered the case of finishing pictures");
- (void) imagePickerControllerDidCancel: (UIImagePickerController *) picker
NSLog(@"Entered the case of cancel");
上述代码的作用是成功启动相机应用程序,但是我不确定 takePicture API 是否能够成功单击图片。我在 Ipad 内的照片应用程序中没有看到任何保存的图片,所以我认为该图片没有被点击。 有人可以告诉我上面的代码是否正确,或者一旦显示相机控件,我需要做什么来自动单击捕获按钮的部分
【问题讨论】:
【参考方案1】:[请转到 Apple 文档中的“使用 UIImagePickerController 选择图片并拍摄照片”,以获取类 UIImagePickerController
的属性 cameraOverlayView
,以获取满足您需要的完整示例应用程序,以及更多内容。]
您将CameraViewController
指定为采用UIImagePickerControllerDelegate
协议,因此您必须实现两条消息:
- (void) imagePickerController: (UIImagePickerController *) picker
didFinishPickingMediaWithInfo: (NSDictionary *) info;
和
- (void) imagePickerControllerDidCancel: (UIImagePickerController *) picker;
正如 iOS 文档所述,NSDictionary* info
有一个密钥 UIImagePickerControllerOriginalImage
,它将返回 UIImage
。像这样访问它:
UIImage *snapshot = (UIImage *) [info objectForKey: UIImagePickerControllerOriginalImage];
由于您的计划是使用 takePicture
自动拍照(无需用户交互),因此请务必指定
picker.showsCameraControls = NO;
【讨论】:
我今天做了更多的阅读。我的要求是在显示相机预览后自动单击图片(用户不应手动单击相机应用程序上的按钮)。我的假设是 takePicture API 会?在我的情况下,didFinishPickingMediaWithInfo 将不起作用,因为用户无法手动单击或选择“使用照片”选项 Apple 文档要求您在以编程方式调用takePicture
时不要显示图像选择器控件。请参阅上面的编辑。
好的,我确实将图像选择器控件添加到否,我已经用最新的代码编辑了我的原始问题,但它仍然没有进入 didFinishPickingMediaWithInfo 函数。我的疑问是 takePicture 是否真的点击了图片?我还能如何进入 didFinishPickingMediaWithInfo API ?
编辑了注释以查看 Apple 示例代码,该代码完全符合您的要求(并且还做得更多)。祝你好运。
我确实参考了这个例子,它非常有见地,但它仍然没有解决我的问题。我希望应用程序自动化到用户甚至不应该按下自定义按钮的程度,但是当我尝试自己调用该方法或模拟按钮按下时,应用程序不会产生预期的结果。我应该尝试添加一个计时器吗?【参考方案2】:
你需要实现 UIImagePIckerControllerDelegate 的 imagePickerController:didFinishPickingMediaWithInfo: 方法。
之后,查看 mediaInfo 字典,里面有一个 UIImage 可以使用。
【讨论】:
我在日志语句中添加了以下代码,但它并没有进入这个函数,是我遗漏了什么吗? -(void) imagePickerController: (UIImagePickerController *) picker didFinishPickingMediaWithInfo: (NSDictionary *) info NSLog(@"进入整理图片的情况"); - (void) imagePickerControllerDidCancel: (UIImagePickerController *) 选择器 【参考方案3】:我知道这是旧的,但使用计时器的更好替代方法(请参阅已接受答案中的 cmets)是实现完成处理程序而不是传入 NULL。
[self presentViewController:picker animated:YES completion:^
NSLog(@"Taking the picture now");
[picker takePicture];
];
这样,每次都能一致地拍摄照片,并且您不会浪费时间添加不必要的延迟。
【讨论】:
【参考方案4】:**You can auto capturing both camera image and video recording by use this code.**
import UIKit
import AVFoundation
import MobileCoreServices
class ViewController: UIViewController, UIGestureRecognizerDelegate
let captureSession = AVCaptureSession()
var captureDevice : AVCaptureDevice?
var imagePicker = UIImagePickerController()
var flagVideoRecording = false
var arrImages = [UIImage]()
var countVideoRecording = 0
var labelTime = UILabel()
var timer: Timer?
override func viewDidLoad()
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(actionRepeatCapturing), name: .AVCaptureSessionDidStartRunning, object: nil)
@objc func actionRepeatCapturing()
flagVideoRecording = false
startCapturingBothImageAndRecordView()
//MARK:- UIButton's Action
@IBAction func actionCaptureImage(_ sender: UIButton)
flagVideoRecording = false
if AVCaptureDevice.authorizationStatus(for: AVMediaType.video) == AVAuthorizationStatus.authorized
startCapturingBothImageAndRecordView()
else
AVCaptureDevice.requestAccess(for: AVMediaType.video, completionHandler: (granted: Bool) -> Void in
if granted == true
self.startCapturingBothImageAndRecordView()
else
DispatchQueue.main.async
self.alertToEncourageAccessInitially("Camera access required for capturing photos!", actionTitle: "Allow Camera")
)
@IBAction func actionCaptureVideo(_ sender: UIButton)
flagVideoRecording = true
if AVCaptureDevice.authorizationStatus(for: AVMediaType.video) == AVAuthorizationStatus.authorized
switch AVAudioSession.sharedInstance().recordPermission
case AVAudioSession.RecordPermission.granted:
self.startCapturingBothImageAndRecordView()
case AVAudioSession.RecordPermission.denied:
self.alertToEncourageAccessInitially("Microphone access required for record your voice!", actionTitle: "Allow Microphone")
case AVAudioSession.RecordPermission.undetermined:
AVAudioSession.sharedInstance().requestRecordPermission( (granted) in
if granted
self.startCapturingBothImageAndRecordView()
else
self.alertToEncourageAccessInitially("Microphone access required for record your voice!", actionTitle: "Allow Microphone")
)
default:
break
else
AVCaptureDevice.requestAccess(for: AVMediaType.video, completionHandler: (granted: Bool) -> Void in
if granted == true
switch AVAudioSession.sharedInstance().recordPermission
case AVAudioSession.RecordPermission.granted:
self.startCapturingBothImageAndRecordView()
case AVAudioSession.RecordPermission.denied:
self.alertToEncourageAccessInitially("Microphone access required for record your voice!", actionTitle: "Allow Microphone")
case AVAudioSession.RecordPermission.undetermined:
AVAudioSession.sharedInstance().requestRecordPermission( (granted) in
if granted
self.startCapturingBothImageAndRecordView()
else
self.alertToEncourageAccessInitially("Microphone access required for record your voice!", actionTitle: "Allow Microphone")
)
default:
break
else
DispatchQueue.main.async
self.alertToEncourageAccessInitially("Camera access required for record video", actionTitle: "Allow Camera")
)
extension ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate
func startCapturingBothImageAndRecordView()
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.camera)
debugPrint("captureVideoPressed and camera available.")
imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .camera
if flagVideoRecording
imagePicker.mediaTypes = [kUTTypeMovie as String]
imagePicker.allowsEditing = false
imagePicker.showsCameraControls = false
let viewTime = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 40))
viewTime.backgroundColor = .black
viewTime.alpha = 0.1
labelTime = UILabel(frame: CGRect(x: self.view.frame.width/2-50, y: 10, width: 100, height: 25))
labelTime.font = UIFont.boldSystemFont(ofSize: 17)
labelTime.text = "00.00:00"
labelTime.textColor = .white
labelTime.textAlignment = .center
labelTime.backgroundColor = .red
imagePicker.view.addSubview(viewTime)
imagePicker.view.addSubview(labelTime)
self.timer = Timer.scheduledTimer(timeInterval: 1,
target: self,
selector: #selector(self.actionStopVideoRecording),
userInfo: nil,
repeats: true)
else
imagePicker.allowsEditing = false
imagePicker.showsCameraControls = false
else
debugPrint("Camera not available.")
self.present(self.imagePicker, animated: true, completion:
if self.flagVideoRecording
self.imagePicker.startVideoCapture()
else
self.imagePicker.takePicture()
)
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any])
if flagVideoRecording
if let videoFileURL = info[UIImagePickerController.InfoKey.mediaURL] as? URL
debugPrint(videoFileURL)
// let data = try Data(contentsOf: videoFileURL, options: .mappedIfSafe)
// debugPrint(data)
self.dismiss(animated: true, completion: nil)
else
if let pickedImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
arrImages.append(pickedImage)
sleep(1)
if arrImages.count >= 5
self.dismiss(animated: true, completion: nil)
else
NotificationCenter.default.post(name: .AVCaptureSessionDidStartRunning, object: nil, userInfo: nil)
@objc func actionStopVideoRecording()
countVideoRecording += 1
labelTime.text = countVideoRecording == 10 ? "00:00:\(countVideoRecording)":"00:00:0\(countVideoRecording)"
if countVideoRecording == 10
imagePicker.stopVideoCapture()
timer?.invalidate()
timer = nil
extension ViewController
func alertToEncourageAccessInitially(_ msgString: String, actionTitle: String)
let alert = UIAlertController(
title: "IMPORTANT",
message: msgString,
preferredStyle: UIAlertController.Style.alert
)
alert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: nil))
alert.addAction(UIAlertAction(title: actionTitle, style: .destructive, handler: (alert) -> Void in
let myUrl = URL(string: UIApplication.openSettingsURLString)!
if let url = URL(string: "\(myUrl)"), !url.absoluteString.isEmpty
UIApplication.shared.open(url, options: [:], completionHandler: nil)
// or outside scope use this
guard let url = URL(string: "\(myUrl)"), !url.absoluteString.isEmpty else
return
UIApplication.shared.open(url, options: [:], completionHandler: nil)
))
present(alert, animated: true, completion: nil)
【讨论】:
以上是关于IOS自动抓图的主要内容,如果未能解决你的问题,请参考以下文章