【问题标题】:Capture picture automatically in IOSIOS自动抓图
【发布时间】: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 内的照片应用程序中没有看到任何保存的图片,所以我认为该图片没有被点击。 有人可以告诉我上面的代码是否正确,或者一旦显示相机控件,我需要做什么来自动单击捕获按钮的部分

【问题讨论】:

    标签: ios ios-camera


    【解决方案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)
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-08-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多