Wie verwende ich die metadataOutputRectOfInterestForRect Methode und rectOfInterest Eigenschaft Scannen einen bestimmten Bereich? (QR-Code)
Baue ich eine QR-code-scanner mit Swift und alles funktioniert in dieser Hinsicht. Das Problem, das ich habe ist, dass ich versuche, nur einen kleinen Bereich des gesamten sichtbaren AVCaptureVideoPreviewLayer
werden in der Lage zu Scannen QR-codes. Ich habe herausgefunden, dass, um anzugeben, welcher Bereich des Bildschirms wird in der Lage sein zu Lesen/erfassen von QR-codes, die ich verwenden würde eine Eigenschaft von AVCaptureMetadataOutput
genannt rectOfInterest
. Das Problem ist, wenn ich zugewiesen, dass zu einem CGRect, konnte ich nicht Scannen nichts. Nach mehr tun, online-Forschung, habe ich festgestellt, dass einige darauf hindeutet, dass ich brauchen würde, um eine Methode namens metadataOutputRectOfInterestForRect
konvertieren CGRect in einem korrekten format, dass die Eigenschaft rectOfInterest
tatsächlich verwenden können. ALLERDINGS ist die große Frage, die ich habe laufen in ist, dass jetzt, wenn ich diese Methode metadataoutputRectOfInterestForRect
ich erhalte eine Fehlermeldung, die besagt CGAffineTransformInvert: singular matrix
. Kann mir jemand sagen warum ich diese Fehlermeldung bekommen? Ich glaube, ich bin mit dieser Methode richtig laut in der Entwicklerdokumentation von Apple und ich glaube, ich benötigen, um dieses nach allen Informationen, die ich gefunden habe online zu erreichen ist mein Ziel. Ich werde auch links zu den Unterlagen, die ich bis jetzt gefunden habe, sowie ein code-Beispiel von der Funktion bin ich mit dem Scannen von QR-codes
CODE-BEISPIEL
func startScan() {
//Get an instance of the AVCaptureDevice class to initialize a device object and provide the video
//as the media type parameter.
let captureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
//Get an instance of the AVCaptureDeviceInput class using the previous device object.
var error:NSError?
let input: AnyObject! = AVCaptureDeviceInput.deviceInputWithDevice(captureDevice, error: &error)
if (error != nil) {
//If any error occurs, simply log the description of it and don't continue any more.
println("\(error?.localizedDescription)")
return
}
//Initialize the captureSession object.
captureSession = AVCaptureSession()
//Set the input device on the capture session.
captureSession?.addInput(input as! AVCaptureInput)
//Initialize a AVCaptureMetadataOutput object and set it as the output device to the capture session.
let captureMetadataOutput = AVCaptureMetadataOutput()
captureSession?.addOutput(captureMetadataOutput)
//calculate a centered square rectangle with red border
let size = 300
let screenWidth = self.view.frame.size.width
let xPos = (CGFloat(screenWidth) / CGFloat(2)) - (CGFloat(size) / CGFloat(2))
let scanRect = CGRect(x: Int(xPos), y: 150, width: size, height: size)
//create UIView that will server as a red square to indicate where to place QRCode for scanning
scanAreaView = UIView()
scanAreaView?.layer.borderColor = UIColor.redColor().CGColor
scanAreaView?.layer.borderWidth = 4
scanAreaView?.frame = scanRect
view.addSubview(scanAreaView!)
//Set delegate and use the default dispatch queue to execute the call back
captureMetadataOutput.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
captureMetadataOutput.metadataObjectTypes = [AVMetadataObjectTypeQRCode]
//Initialize the video preview layer and add it as a sublayer to the viewPreview view's layer.
videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
videoPreviewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
videoPreviewLayer?.frame = view.layer.bounds
captureMetadataOutput.rectOfInterest = videoPreviewLayer!.metadataOutputRectOfInterestForRect(scanRect)
view.layer.addSublayer(videoPreviewLayer)
//Start video capture.
captureSession?.startRunning()
//Initialize QR Code Frame to highlight the QR code
qrCodeFrameView = UIView()
qrCodeFrameView?.layer.borderColor = UIColor.greenColor().CGColor
qrCodeFrameView?.layer.borderWidth = 2
view.addSubview(qrCodeFrameView!)
view.bringSubviewToFront(qrCodeFrameView!)
//Add a button that will be used to close out of the scan view
videoBtn.setTitle("Close", forState: .Normal)
videoBtn.setTitleColor(UIColor.blackColor(), forState: .Normal)
videoBtn.backgroundColor = UIColor.grayColor()
videoBtn.layer.cornerRadius = 5.0;
videoBtn.frame = CGRectMake(10, 30, 70, 45)
videoBtn.addTarget(self, action: "pressClose:", forControlEvents: .TouchUpInside)
view.addSubview(videoBtn)
view.bringSubviewToFront(scanAreaView!)
}
Bitte beachten Sie, dass die Linie von Interesse, die den Fehler verursacht, ist dies:
captureMetadataOutput.rectOfInterest = videoPreviewLayer!.metadataOutputRectOfInterestForRect(scanRect)
Andere Dinge, die ich versucht habe sind vorbei in einem CGRect direkt als parameter und das hat verursacht den gleichen Fehler. Ich habe auch bestanden in scanAreaView!.bounds
als parameter, wie das ist, wirklich die genaue Größe/Fläche ich bin auf der Suche nach und das verursacht auch die gleichen Fehler. Ich habe gesehen, das dies in anderen code-Beispiele online und Sie scheinen nicht zu haben die Fehler, die ich habe. Hier sind einige Beispiele:
Apple-Dokumentation
metadataOutputRectOfInterestForRect
Bild von scanAreaView ich benutze den dafür vorgesehenen Bereich, den ich versuche zu machen, die nur scannbarer Bereich der video-Vorschau-Schicht:
- Was kann verwendet werden, wenn mit AVCapturePhotoCaptureDelegate die func photoOutput(_ Ausgabe: AVCapturePhotoOutput, didFinishProcessingPhoto Foto: AVCapturePhoto, Fehler: Fehler?) statt ?
Du musst angemeldet sein, um einen Kommentar abzugeben.
War ich nicht wirklich in der Lage zu klären, das Problem mit metadataOutputRectOfInterestForRect, jedoch, können Sie direkt die Eigenschaft als gut. Sie müssen die haben, die Auflösung in der Breite und Höhe des Videos, die Sie im Voraus festlegen. Ich schnell verwendet die Auflösung von 640*480 einstellen. Wie in der Dokumentation erwähnt, sind die Werte zu
Sehen https://developer.apple.com/documentation/avfoundation/avcaptureoutput/1616304-metadataoutputrectofinterestforr
Unten ist der code, den ich versucht
Habe es gerade getestet auf einem iOS-Gerät und es scheint zu funktionieren.
Bearbeiten
Zumindest habe ich gelöst, die metadataOutputRectOfInterestForRect problem. Ich glaube, Sie müssen dies tun, nachdem Sie die Kamera ordnungsgemäß festgelegt wurde und ausgeführt wird, wie die Kamera-Auflösung ist noch nicht verfügbar.
Fügen Sie zunächst eine Benachrichtigung der Beobachter-Methode in viewDidLoad()
Dann fügen Sie die folgende Methode
Hier kannst du dann wieder in die rectOfInterest Eigenschaft. Dann, in Ihrem code, können Sie die Anzeige der AVMetadataObject innerhalb der didOutputMetadataObjects Funktion
Ich habe versucht, und das Rechteck war immer im angegebenen Bereich.
In iOS 9.3.2 konnte ich
metadataoutputRectOfInterestForRect
Arbeit ruft Sie gleich nachstartRunning
Methode derAVCaptureSession
:Swift 4:
Habe ich es geschafft einen Effekt zu erstellen, dass eine region von Interesse. Ich habe versucht, alle vorgeschlagenen Lösungen, aber die region war es entweder ein CGPoint.null oder hatte unangemessenen Größe (nach der Konvertierung von frames, um eine 0-1-Koordinate). Es ist eigentlich ein hack für diejenigen, die nicht bekommen kann die
regionOfInterest
zu arbeiten und nicht die Optimierung der Erkennung.In:
Ich habe den folgenden code:
///Nach
///Fügen Sie diese
Lesen QRCode/BarCode aus einer kleinen rect(region) von einer vollen Kamera-Ansicht.
Hinweis:
captureMetadataOutput
--> AVCaptureMetadataOutput_videoPreviewLayer
--> AVCaptureVideoPreviewLayerscanRect
--> Rect wo Sie wollen, dass der QRCode gelesen werden.Schrieb ich Folgendes:
Und dieses arbeitete für mich, aber ich weiß immer noch nicht, warum.