Files
kapture/Sources/Kapture/OCRService.swift
T
TZGyn 195c6a9b1f Enable automatic language detection so CJK text is recognized
Vision defaulted to the first listed language and turned Chinese into
Latin garbage (你好世界 became 177WR). automaticallyDetectsLanguage fixes
it; the smoke test now covers Chinese so it cannot regress.

💘 Generated with Crush

Assisted-by: Crush:deepseek-v4-flash-0731
2026-09-22 10:54:54 +08:00

42 lines
1.5 KiB
Swift

import AppKit
import Vision
final class OCRService {
static let shared = OCRService()
private let queue = DispatchQueue(label: "dev.tzgyn.kapture.ocr", qos: .userInitiated)
func recognize(_ cgImage: CGImage, completion: @escaping (String) -> Void) {
queue.async {
let request = VNRecognizeTextRequest()
request.recognitionLevel = .accurate
request.usesLanguageCorrection = true
request.recognitionLanguages = ["en-US", "zh-Hans", "zh-Hant", "ja-JP", "ko-KR"]
// Without this, Vision defaults to the first listed language and
// renders CJK as Latin garbage (verified: 你好世界 -> "177WR").
if #available(macOS 13.0, *) {
request.automaticallyDetectsLanguage = true
}
let handler = VNImageRequestHandler(cgImage: cgImage, options: [:])
do {
try handler.perform([request])
} catch {
completion("")
return
}
let observations = request.results ?? []
let lines = observations
.sorted { a, b in
let ay = a.boundingBox.midY
let by = b.boundingBox.midY
if abs(ay - by) > 0.02 { return ay > by }
return a.boundingBox.minX < b.boundingBox.minX
}
.compactMap { $0.topCandidates(1).first?.string }
completion(lines.joined(separator: "\n"))
}
}
}