2017-12-14 9 views
0

AVCaptureMetadataOutputとrectOfInterestを使用してスキャン制限の問題があります。私は正常にスキャン領域が正しいことを確認するUIImageを描画しました。ios rectOfInterest AVCaptureMetadataOutput無視する

しかし、私が行うことは、スキャン項目が画面の絶対的な中央にある場合にのみ機能します。 私のrectを無視しているようです。

出力サイズ

Display size width: 414, height: 736 
Percent size width: 0.724638, height: 0.407609 
Crop search area: {{57, 218}, {300, 300}} 
Crop search converted: {{0.29619565217391297, 0.13768115942028991},   {0.40760869565217395, 0.72463768115942029}} 

ここ enter image description here

そして、実際の方法描かれた黄色の矩形です。完全なコードは時々返す{{0,0}、{0,0}、私が知っている限りでは、

scanBarcodeArea = [_previewLayer metadataOutputRectOfInterestForRect:scanLimit]; 
     [metadataOutput setRectOfInterest:scanBarcodeArea]; 

このコードは常に正しいRECTを返すことができませんでしたここhttps://github.com/fbacker/react-native-camera/blob/barcode-finder/ios/RCTCameraManager.m

- (void)startSession { 
#if TARGET_IPHONE_SIMULATOR 
    return; 
#endif 
    dispatch_async(self.sessionQueue, ^{ 
    if (self.presetCamera == AVCaptureDevicePositionUnspecified) { 
     self.presetCamera = AVCaptureDevicePositionBack; 
    } 

    AVCaptureStillImageOutput *stillImageOutput = [[AVCaptureStillImageOutput alloc] init]; 
    if ([self.session canAddOutput:stillImageOutput]) 
    { 
     stillImageOutput.outputSettings = @{AVVideoCodecKey : AVVideoCodecJPEG}; 
     [self.session addOutput:stillImageOutput]; 
     self.stillImageOutput = stillImageOutput; 
    } 

    AVCaptureMovieFileOutput *movieFileOutput = [[AVCaptureMovieFileOutput alloc] init]; 
    if ([self.session canAddOutput:movieFileOutput]) 
    { 
     [self.session addOutput:movieFileOutput]; 
     self.movieFileOutput = movieFileOutput; 
    } 

    AVCaptureMetadataOutput *metadataOutput = [[AVCaptureMetadataOutput alloc] init]; 
    CGRect scanBarcodeArea = CGRectMake(0, 0, 0, 0); 
    if ([self.session canAddOutput:metadataOutput]) { 

     [self.session addOutput:metadataOutput]; 
     [metadataOutput setMetadataObjectsDelegate:self queue:self.sessionQueue]; 
     [metadataOutput setMetadataObjectTypes:self.barCodeTypes]; 

     // we only want to scan specified area 
     // NOTE; Seems we can only set the actual rect after session started, else it doesn't work 
     if (self.barcodeFinderVisible) { 

      NSNumber *imageWidth = [NSNumber numberWithFloat:self.previewLayer.frame.size.width]; 
      NSNumber *imageHeight = [NSNumber numberWithFloat:self.previewLayer.frame.size.height]; 
      double imageUseWidth = [imageWidth doubleValue]; 
      double imageUseHeight = [imageHeight doubleValue]; 
      double cropWidth = imageUseWidth * self.barcodeFinderPercentageSizeWidth; 
      double cropHeight = imageUseHeight * self.barcodeFinderPercentageSizeHeight; 
      double cropX = (imageUseWidth/2)-(cropWidth/2); 
      double cropY = (imageUseHeight/2)-(cropHeight/2); 
      CGRect scanLimit = CGRectMake(cropX, cropY, cropWidth, cropHeight); 
      scanBarcodeArea = [_previewLayer metadataOutputRectOfInterestForRect:scanLimit]; 
      [metadataOutput setRectOfInterest:scanBarcodeArea]; 

     /* ############################ 
     DEBUG PURPOSE, get some values and draw yellow rect of actual scanning area 
     */ 

      /* 
      NSLog(@"Display size width: %@, height: %@", imageWidth, imageHeight); 
      NSLog(@"Percent size width: %f, height: %f", self.barcodeFinderPercentageSizeWidth, self.barcodeFinderPercentageSizeHeight); 
      NSLog(@"Crop search area: %@", NSStringFromCGRect(scanLimit)); 
      NSLog(@"Crop search converted: %@", NSStringFromCGRect(scanBarcodeArea)); 

      // PAUSE AND PLAY WILL DRAW YELLOW RECT, IF VALID, might appear auto as well. who knows. 
      UIView *scanAreaView = [[UIView alloc] initWithFrame:scanLimit]; 
      scanAreaView.layer.borderColor = [UIColor yellowColor].CGColor; 
      scanAreaView.layer.borderWidth = 4; 
      [self.view addSubview:scanAreaView]; 
      */ 
     } 
    } 
    self.metadataOutput = metadataOutput; 

    __weak RCTCameraManager *weakSelf = self; 
    [self setRuntimeErrorHandlingObserver:[NSNotificationCenter.defaultCenter addObserverForName:AVCaptureSessionRuntimeErrorNotification object:self.session queue:nil usingBlock:^(NSNotification *note) { 
     RCTCameraManager *strongSelf = weakSelf; 
     dispatch_async(strongSelf.sessionQueue, ^{ 
     // Manually restarting the session since it must have been stopped due to an error. 
     [strongSelf.session startRunning]; 
     }); 
    }]]; 

    [self.session startRunning]; 
    }); 
} 

答えて

0

を表示することができます}私はrect-navigationを使っているので、カメラの画面に移動して戻ってカメラに再度移動すると、{{0,0}、{0,0}}が表示され、誰かがpreviewLayerを初期化していないよく

と私は最初に私のアプリを実行し、第1のカメラの画面に移動し、また、{{0,0}、{0,0}}取得するときに、私は

[self.session startRunning]; 

後にこのコードを入れていても。

したがって、私はrectOrangeを計算するためにmetadataOutputRectOfInterestForRectの代わりにこれらのブローコードを使用します。

 NSNumber *imageWidth = [NSNumber numberWithFloat:self.previewLayer.frame.size.width]; 
     NSNumber *imageHeight = [NSNumber numberWithFloat:self.previewLayer.frame.size.height]; 

     double imageUseWidth = [imageWidth doubleValue]; 
     double imageUseHeight = [imageHeight doubleValue]; 
     double cropWidth = imageUseWidth * self.barcodeFinderPercentageSizeWidth; 
     double cropHeight = imageUseHeight * self.barcodeFinderPercentageSizeHeight; 
     double cropX = (imageUseWidth/2)-(cropWidth/2); 
     double cropY = ((imageUseHeight)/2)-(cropHeight/2); 

     // transform to camera coordinate 
     double scanX = cropY/imageUseHeight; 
     double scanY = cropX/imageUseWidth; 
     double scanWidth = cropHeight/imageUseHeight; 
     double scanHeight = cropWidth/imageUseWidth; 

     CGRect rectOfInterest = CGRectMake(scanX, scanY, scanWidth, scanHeight); 
+0

戻り値には常に何かがあります。また、[self.session startRunning]の後に私とあなたのコードを試しました。まったく同じ結果になります。 – roady

+0

注:rectOfInterest = {{y、x}、{height、width}}; // {{0,0}、{1,1}}、私は理由を知らないし、googleから何の説明も見つけられない。 – acoder

関連する問題