예제 #1
0
        private void ApplyCameraSettings()
        {
            var parameters = Camera.GetParameters();

            parameters.PreviewFormat = ImageFormatType.Nv21;

            var supportedFocusModes = parameters.SupportedFocusModes;

            if (Build.VERSION.SdkInt >= BuildVersionCodes.IceCreamSandwich &&
                supportedFocusModes.Contains(Camera.Parameters.FocusModeContinuousPicture))
            {
                parameters.FocusMode = Camera.Parameters.FocusModeContinuousPicture;
            }
            else if (supportedFocusModes.Contains(Camera.Parameters.FocusModeContinuousVideo))
            {
                parameters.FocusMode = Camera.Parameters.FocusModeContinuousVideo;
            }
            else if (supportedFocusModes.Contains(Camera.Parameters.FocusModeAuto))
            {
                parameters.FocusMode = Camera.Parameters.FocusModeAuto;
            }
            else if (supportedFocusModes.Contains(Camera.Parameters.FocusModeFixed))
            {
                parameters.FocusMode = Camera.Parameters.FocusModeFixed;
            }

            var selectedFps = parameters.SupportedPreviewFpsRange.FirstOrDefault();

            if (selectedFps != null)
            {
                // This will make sure we select a range with the lowest minimum FPS
                // and maximum FPS which still has the lowest minimum
                // This should help maximize performance / support for hardware
                foreach (var fpsRange in parameters.SupportedPreviewFpsRange)
                {
                    if (fpsRange[0] <= selectedFps[0] && fpsRange[1] > selectedFps[1])
                    {
                        selectedFps = fpsRange;
                    }
                }
                parameters.SetPreviewFpsRange(selectedFps[0], selectedFps[1]);
            }

            var availableResolutions = parameters.SupportedPreviewSizes.Select(sps => new CameraResolution
            {
                Width  = sps.Width,
                Height = sps.Height
            });

            // Try and get a desired resolution from the options selector
            var resolution = _scanningOptions.GetResolution(availableResolutions.ToList());

            // If the user did not specify a resolution, let's try and find a suitable one
            if (resolution == null)
            {
                foreach (var sps in parameters.SupportedPreviewSizes)
                {
                    if (sps.Width >= 640 && sps.Width <= 1000 && sps.Height >= 360 && sps.Height <= 1000)
                    {
                        resolution = new CameraResolution
                        {
                            Width  = sps.Width,
                            Height = sps.Height
                        };
                        break;
                    }
                }
            }

            // Google Glass requires this fix to display the camera output correctly
            if (Build.Model.Contains("Glass"))
            {
                resolution = new CameraResolution
                {
                    Width  = 640,
                    Height = 360
                };
                // Glass requires 30fps
                parameters.SetPreviewFpsRange(30000, 30000);
            }

            // Hopefully a resolution was selected at some point
            if (resolution != null)
            {
                Android.Util.Log.Debug(MobileBarcodeScanner.TAG,
                                       "Selected Resolution: " + resolution.Width + "x" + resolution.Height);
                parameters.SetPreviewSize(resolution.Width, resolution.Height);
            }

            Camera.SetParameters(parameters);

            SetCameraDisplayOrientation();
        }
        bool SetupCaptureSession()
        {
            var availableResolutions = new List <CameraResolution> ();

            var consideredResolutions = new Dictionary <NSString, CameraResolution> {
                { AVCaptureSession.Preset352x288, new CameraResolution   {
                      Width = 352, Height = 288
                  } },
                { AVCaptureSession.PresetMedium, new CameraResolution    {
                      Width = 480, Height = 360
                  } },                                                                                      //480x360
                { AVCaptureSession.Preset640x480, new CameraResolution   {
                      Width = 640, Height = 480
                  } },
                { AVCaptureSession.Preset1280x720, new CameraResolution  {
                      Width = 1280, Height = 720
                  } },
                { AVCaptureSession.Preset1920x1080, new CameraResolution {
                      Width = 1920, Height = 1080
                  } }
            };

            // configure the capture session for low resolution, change this if your code
            // can cope with more data or volume
            session = new AVCaptureSession()
            {
                SessionPreset = AVCaptureSession.Preset640x480
            };

            // create a device input and attach it to the session
//			var captureDevice = AVCaptureDevice.DefaultDeviceWithMediaType (AVMediaType.Video);
            AVCaptureDevice captureDevice = null;
            var             devices       = AVCaptureDevice.DevicesWithMediaType(AVMediaType.Video);

            foreach (var device in devices)
            {
                captureDevice = device;
                if (ScanningOptions.UseFrontCameraIfAvailable.HasValue &&
                    ScanningOptions.UseFrontCameraIfAvailable.Value &&
                    device.Position == AVCaptureDevicePosition.Front)
                {
                    break;                     //Front camera successfully set
                }
                else if (device.Position == AVCaptureDevicePosition.Back && (!ScanningOptions.UseFrontCameraIfAvailable.HasValue || !ScanningOptions.UseFrontCameraIfAvailable.Value))
                {
                    break;                     //Back camera succesfully set
                }
            }
            if (captureDevice == null)
            {
                Console.WriteLine("No captureDevice - this won't work on the simulator, try a physical device");
                if (overlayView != null)
                {
                    this.AddSubview(overlayView);
                    this.BringSubviewToFront(overlayView);
                }
                return(false);
            }

            CameraResolution resolution = null;

            // Find resolution
            // Go through the resolutions we can even consider
            foreach (var cr in consideredResolutions)
            {
                // Now check to make sure our selected device supports the resolution
                // so we can add it to the list to pick from
                if (captureDevice.SupportsAVCaptureSessionPreset(cr.Key))
                {
                    availableResolutions.Add(cr.Value);
                }
            }

            resolution = ScanningOptions.GetResolution(availableResolutions);

            // See if the user selected a resolution
            if (resolution != null)
            {
                // Now get the preset string from the resolution chosen
                var preset = (from c in consideredResolutions
                              where c.Value.Width == resolution.Width &&
                              c.Value.Height == resolution.Height
                              select c.Key).FirstOrDefault();

                // If we found a matching preset, let's set it on the session
                if (!string.IsNullOrEmpty(preset))
                {
                    session.SessionPreset = preset;
                }
            }

            var input = AVCaptureDeviceInput.FromDevice(captureDevice);

            if (input == null)
            {
                Console.WriteLine("No input - this won't work on the simulator, try a physical device");
                if (overlayView != null)
                {
                    this.AddSubview(overlayView);
                    this.BringSubviewToFront(overlayView);
                }
                return(false);
            }
            else
            {
                session.AddInput(input);
            }


            foundResult = false;
            //Detect barcodes with built in avcapture stuff
            AVCaptureMetadataOutput metadataOutput = new AVCaptureMetadataOutput();

            captureDelegate = new CaptureDelegate(metaDataObjects =>
            {
                if (!analyzing)
                {
                    return;
                }

                //Console.WriteLine("Found MetaData Objects");

                var msSinceLastPreview = (DateTime.UtcNow - lastAnalysis).TotalMilliseconds;

                if (msSinceLastPreview < ScanningOptions.DelayBetweenAnalyzingFrames ||
                    (wasScanned && msSinceLastPreview < ScanningOptions.DelayBetweenContinuousScans) ||
                    working)
                //|| CancelTokenSource.IsCancellationRequested)
                {
                    return;
                }

                try {
                    working      = true;
                    wasScanned   = false;
                    lastAnalysis = DateTime.UtcNow;

                    var mdo = metaDataObjects.FirstOrDefault();

                    var readableObj = mdo as AVMetadataMachineReadableCodeObject;

                    if (readableObj == null)
                    {
                        return;
                    }

                    wasScanned = true;

                    var zxingFormat = ZXingBarcodeFormatFromAVCaptureBarcodeFormat(readableObj.Type.ToString());

                    var rs = new ZXing.Result(readableObj.StringValue, null, null, zxingFormat);

                    resultCallback(rs);
                } finally {
                    working = false;
                }
            });

            metadataOutput.SetDelegate(captureDelegate, DispatchQueue.MainQueue);
            session.AddOutput(metadataOutput);

            //Setup barcode formats
            if (ScanningOptions.PossibleFormats != null && ScanningOptions.PossibleFormats.Count > 0)
            {
                #if __UNIFIED__
                var formats = AVMetadataObjectType.None;

                foreach (var f in ScanningOptions.PossibleFormats)
                {
                    formats |= AVCaptureBarcodeFormatFromZXingBarcodeFormat(f);
                }

                formats &= ~AVMetadataObjectType.None;

                metadataOutput.MetadataObjectTypes = formats;
                #else
                var formats = new List <string> ();

                foreach (var f in ScanningOptions.PossibleFormats)
                {
                    formats.AddRange(AVCaptureBarcodeFormatFromZXingBarcodeFormat(f));
                }

                metadataOutput.MetadataObjectTypes = (from f in formats.Distinct() select new NSString(f)).ToArray();
                #endif
            }
            else
            {
                metadataOutput.MetadataObjectTypes = metadataOutput.AvailableMetadataObjectTypes;
            }



            previewLayer = new AVCaptureVideoPreviewLayer(session);

            // //Framerate set here (15 fps)
            //          if (previewLayer.RespondsToSelector(new Selector("connection")))
            //          {
            //  if (UIDevice.CurrentDevice.CheckSystemVersion (7, 0))
            //  {
            //      var perf1 = PerformanceCounter.Start ();

            //      NSError lockForConfigErr = null;

            //      captureDevice.LockForConfiguration (out lockForConfigErr);
            //      if (lockForConfigErr == null)
            //      {
            //          captureDevice.ActiveVideoMinFrameDuration = new CMTime (1, 10);
            //          captureDevice.UnlockForConfiguration ();
            //      }

            //      PerformanceCounter.Stop (perf1, "PERF: ActiveVideoMinFrameDuration Took {0} ms");
            //  }
            //              else
            //                  previewLayer.Connection.VideoMinFrameDuration = new CMTime(1, 10);
            //          }

                        #if __UNIFIED__
            previewLayer.VideoGravity = AVLayerVideoGravity.ResizeAspectFill;
                        #else
            previewLayer.LayerVideoGravity = AVLayerVideoGravity.ResizeAspectFill;
                        #endif
            previewLayer.Frame    = new CGRect(0, 0, this.Frame.Width, this.Frame.Height);
            previewLayer.Position = new CGPoint(this.Layer.Bounds.Width / 2, (this.Layer.Bounds.Height / 2));

            layerView = new UIView(new CGRect(0, 0, this.Frame.Width, this.Frame.Height));
            layerView.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight;
            layerView.Layer.AddSublayer(previewLayer);

            this.AddSubview(layerView);

            ResizePreview(UIApplication.SharedApplication.StatusBarOrientation);

            if (overlayView != null)
            {
                this.AddSubview(overlayView);
                this.BringSubviewToFront(overlayView);

                //overlayView.LayoutSubviews ();
            }

            session.StartRunning();

            Console.WriteLine("RUNNING!!!");



            //output.AlwaysDiscardsLateVideoFrames = true;


            Console.WriteLine("SetupCamera Finished");

            //session.AddOutput (output);
            //session.StartRunning ();


            if (captureDevice.IsFocusModeSupported(AVCaptureFocusMode.ContinuousAutoFocus))
            {
                NSError err = null;
                if (captureDevice.LockForConfiguration(out err))
                {
                    if (captureDevice.IsFocusModeSupported(AVCaptureFocusMode.ContinuousAutoFocus))
                    {
                        captureDevice.FocusMode = AVCaptureFocusMode.ContinuousAutoFocus;
                    }
                    else if (captureDevice.IsFocusModeSupported(AVCaptureFocusMode.AutoFocus))
                    {
                        captureDevice.FocusMode = AVCaptureFocusMode.AutoFocus;
                    }

                    if (captureDevice.IsExposureModeSupported(AVCaptureExposureMode.ContinuousAutoExposure))
                    {
                        captureDevice.ExposureMode = AVCaptureExposureMode.ContinuousAutoExposure;
                    }
                    else if (captureDevice.IsExposureModeSupported(AVCaptureExposureMode.AutoExpose))
                    {
                        captureDevice.ExposureMode = AVCaptureExposureMode.AutoExpose;
                    }

                    if (captureDevice.IsWhiteBalanceModeSupported(AVCaptureWhiteBalanceMode.ContinuousAutoWhiteBalance))
                    {
                        captureDevice.WhiteBalanceMode = AVCaptureWhiteBalanceMode.ContinuousAutoWhiteBalance;
                    }
                    else if (captureDevice.IsWhiteBalanceModeSupported(AVCaptureWhiteBalanceMode.AutoWhiteBalance))
                    {
                        captureDevice.WhiteBalanceMode = AVCaptureWhiteBalanceMode.AutoWhiteBalance;
                    }

                    if (UIDevice.CurrentDevice.CheckSystemVersion(7, 0) && captureDevice.AutoFocusRangeRestrictionSupported)
                    {
                        captureDevice.AutoFocusRangeRestriction = AVCaptureAutoFocusRangeRestriction.Near;
                    }

                    if (captureDevice.FocusPointOfInterestSupported)
                    {
                        captureDevice.FocusPointOfInterest = new CGPoint(0.5f, 0.5f);
                    }

                    if (captureDevice.ExposurePointOfInterestSupported)
                    {
                        captureDevice.ExposurePointOfInterest = new CGPoint(0.5f, 0.5f);
                    }

                    captureDevice.UnlockForConfiguration();
                }
                else
                {
                    Console.WriteLine("Failed to Lock for Config: " + err.Description);
                }
            }

            return(true);
        }