LoginSignup
1
1

More than 1 year has passed since last update.

QR読込範囲指定

Last updated at Posted at 2022-02-13

はじめに

QR読取時に読取範囲を指定する必要があったのだが、なかなか思うように範囲を設定できなかったのでログに残しておく。

CGRect直で読取り範囲を算出(失敗)

AVCaptureMetadataOutputインスタンスのrectOfInterestプロパティにCGRectインスタンスを使って読取範囲を指定するサンプルをいくつか見つけたのだが、意図通りに読取範囲を指定することができなかった(Y軸にずれがある)。

// CGRectで指定しているサンプル
self.metadataOutput.rectOfInterest = CGRect(x: frame.minY,y: 1-frame.minX-frame.size.width, width: frame.size.height,height: frame.size.width)

[参考]

[難点]

  1. 座標とサイズの指定が割合の値である。
  2. カメラの向きが横(Landscape)になっており、xyが反転している
  3. 実機による検証で、実際にどこが読み取り範囲になっているのかを確認する方法がわからない(分かる人がいたら教えてください)

自分としては、1.と2.については配慮して値を割り出したつもりだったのだが意図通りの動作にならない。

AVCaptureVideoPreviewLayermetadataOutputRectConvertedメソッドを使用(成功)

rectOfInterestの設定値を、自力で割り出すのではなく、AVCaptureVideoPreviewLayermetadataOutputRectConvertedメソッドで変換すると意図通りに読取り範囲を指定できた。

// preview: AVCaptureVideoPreviewLayerインスタンスを入れるUIViewインスタンス
// previewLayer: AVCaptureVideoPreviewLayerインスタンス
// metadataOutput: AVCaptureMetadataOutputインスタンス

let size = 240
let screenWidth = preview.frame.size.width
let screenHeight = preview.frame.size.height
let xPos = (CGFloat(screenWidth) / CGFloat(2)) - (CGFloat(size) / CGFloat(2))
let yPos = (CGFloat(screenHeight) / CGFloat(2)) - (CGFloat(size) / CGFloat(2))
let scanRect = CGRect(x: Int(xPos), y: Int(yPos), width: size, height: size)

// rectOfInterestに入れる値をAVCaptureVideoPreviewLayerインスタンスのmetadataOutputRectConvertedメソッド経由で算出
self.metadataOutput.rectOfInterest = self.previewLayer.metadataOutputRectConverted(fromLayerRect: scanRect)
let v = UIView()
v.layer.borderWidth = 1
v.layer.borderColor = UIColor.red.cgColor
v.frame = scanRect
preview.addSubview(v)

[参考]
- AVCaptureMetadataOutput().rectOfInterest not Working

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1