0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

案内PDFに申込先のURLが無い? → QRコードの中にしか無かった。pdftoppm と Swift の Vision で全部読み出す

0
Posted at

展示会の案内PDFから、出展やセミナーの申込先を一覧にしようとしました。まず pdftotext で文字を抜いてURLを探しましたが、1本も出てきません。「申込先が書かれていない案内」として報告しかけたところで、紙面にQRコードが並んでいることに気づきました。

数えると、申込の入口は7本。そのうち6本はQRコードの中にしかURLが無く、本文の文字から拾えたものは0本でした。チラシの面は画像1枚で、文字として抜けるものがそもそもありません。

原因

pdftotext が取り出すのは PDF の中の文字だけです。QRコードは画像なので、中のURLは出てきません。案内のチラシは「詳しくはQRから」で済ませてURLを書かないことが多く、文字だけ見ると「申込先なし」に見えます。

直し方1:ページを画像にする

poppler の pdftoppm で、ページを高めの解像度で PNG にします(Homebrew なら brew install poppler)。

pdftoppm -r 400 -png flyer.pdf page
# page-1.png, page-2.png ... ができる

直し方2:Swift の Vision で QR を読む

macOS なら、標準の Vision フレームワークで QR を読めます。swiftc は Command Line Tools に入っているので、追加で入れるものはありません。

readqr.swift
import Foundation
import Vision
import AppKit

// 使い方: ./readqr page-1.png page-2.png ...
for path in CommandLine.arguments.dropFirst() {
    guard let img = NSImage(contentsOfFile: path),
          let cg = img.cgImage(forProposedRect: nil, context: nil, hints: nil) else {
        print("\(path)\t読めない"); continue
    }
    let req = VNDetectBarcodesRequest()
    req.symbologies = [.qr]
    try VNImageRequestHandler(cgImage: cg).perform([req])
    let found = req.results ?? []
    print("\(path)\tQR \(found.count) 個")
    for r in found {
        let b = r.boundingBox  // 左下が原点・0〜1 の割合
        print(String(format: "  x=%.2f y=%.2f\t%@", b.midX, b.midY, r.payloadStringValue ?? "(文字なし)"))
    }
}
swiftc -O readqr.swift -o readqr
./readqr page-*.png
# page-1.png	QR 2 個
#   x=0.71 y=0.44	https://example.com/apply-b
#   x=0.21 y=0.44	https://example.com/apply-a

直し方3:数と位置を紙面と突き合わせる

  • 読めた個数が、紙面のQRの個数と合うかを数えます。 足りなければ解像度を上げるか、QRのあたりを切り抜いてから読み直します。小さいQRが並んでいると、400dpiでも取りこぼすことがあります
  • 出力の順番は紙面の順番ではありません。boundingBox の位置(x が左右、y が上下。y は下から数える)で、「どのQRがどの申込か」を紙面の見出しと対応させます。URLだけ並べても、どれが何の申込か分かりません
  • 短縮URLは、行き先を確かめてから使います
curl -sSL -o /dev/null -w '%{url_effective}\n' https://短縮URL

読めたら、開いて確かめる

URLが読めたことと、申し込めることは別です。今回は読み出した申込先を実際に開くと、3本はもう締切か満席でした。一覧にするなら「開いて受付中か」まで見て書きます。

まとめ

  • 案内PDFの申込先は、QRコードの中にしか無いことがある。pdftotext で何も出なくても「書かれていない」とは言えない
  • pdftoppm で画像にして、Swift の VNDetectBarcodesRequest で読む。macOS なら追加のライブラリは要らない
  • 読めた個数を紙面と数え合わせ、位置で対応を付け、開いて受付中かを確かめる

生成AI(Claude Code)に書かせて一人で会社を回している記録を note に書いています。
https://note.com/kaito_cometa

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?