Vision Framework是苹果在iOS 11中引入的计算机视觉框架,从iOS 13开始加入了强大的文字识别能力(OCR)。借助VNRecognizeTextRequest,开发者可以直接在本地完成图片文字识别,无需联网,也无需引入任何第三方SDK。更重要的是,Vision不仅返回识别出的文字内容,还会返回每段文字在图片中的精确坐标,这为内容提取、翻译标注、证件信息读取等场景提供了极大便利。本文将从基础API讲起,逐步实现一个支持多语言识别并提取文字坐标的完整方案。
一、Vision OCR的核心API与基本用法
实现文字识别的核心类是VNRecognizeTextRequest,它会分析输入的图片,返回一组VNRecognizedTextObservation对象。每个observation对应图片中的一行文字,其中包含了候选识别结果和该行文字的位置信息。
最基础的调用方式如下,将图片交给VNImageRequestHandler处理即可。整个过程在本地完成,识别速度取决于图片大小和识别模式,一般一张普通截图在1秒内即可完成:
import Vision
import UIKit
func recognizeText(in image: UIImage) {
guard let cgImage = image.cgImage else { return }
let request = VNRecognizeTextRequest { request, error in
guard let observations = request.results as? [VNRecognizedTextObservation] else {
return
}
for observation in observations {
// 取出置信度最高的候选结果
if let candidate = observation.topCandidates(1).first {
print("识别文字:\(candidate.string)")
print("置信度:\(candidate.confidence)")
print("坐标:\(observation.boundingBox)")
}
}
}
let handler = VNImageRequestHandler(cgImage: cgImage, options: [:])
try? handler.perform([request])
}
这段代码中有两个关键点需要理解。第一,topCandidates(1)返回识别候选结果,OCR引擎对同一行文字可能给出多个猜测,通常取第一个即可,其confidence属性表示置信度(0到1之间),可以据此过滤掉不可靠的结果。第二,回调默认在后台线程执行,如果需要更新UI,必须切换回主线程。
二、配置多语言识别与识别模式
Vision默认只支持英文识别,要识别中文、日文、韩文等其他语言,必须显式设置recognitionLanguages属性。该属性接受一个语言代码数组,引擎会按照数组顺序尝试匹配。常见的语言代码包括zh-Hans(简体中文)、zh-Hant(繁体中文)、ja(日文)、ko(韩文)、en-US(美式英文)等。
// iOS 16及以上使用 recognitionLanguages request.recognitionLanguages = ["zh-Hans", "en-US", "ja", "ko"] // iOS 16之前旧属性(已废弃,但需兼容旧系统时会用到) // request.recognitionLevel = .accurate // 设置只返回可信度高的结果 request.usesLanguageCorrection = true
除了语言配置,recognitionLevel还提供两种识别模式:.fast快速模式速度快但准确率略低,适合实时相机取景场景;.accurate精确模式基于更强大的神经网络引擎,准确率明显更高,适合处理静态图片。此外,usesLanguageCorrection开启后引擎会利用语言模型对结果进行纠错,对常规印刷体文字效果显著,但对特殊符号、序列号等场景建议关闭,以免纠错反而破坏原始内容。
还有一个容易被忽略的细节:语言数组的顺序会影响识别结果。如果第一项设置为zh-Hans,引擎会优先按中文习惯断句和识别;如果你的图片以英文为主,应把en-US放在前面。实际项目中建议根据业务场景测试不同顺序的效果。
三、boundingBox坐标系详解与坐标转换
Vision返回的boundingBox使用的是归一化坐标系,取值范围0到1,原点在图片左下角,x轴向右、y轴向上。这与UIKit的坐标系(原点在左上角,y轴向下)完全不同,如果直接拿boundingBox去绘制识别框,位置必然错乱。
下图说明了坐标换算的思路:对于同一个矩形,Vision的y值需要用1减去顶部和底部的值来翻转,宽度高度则乘以实际图片尺寸得到像素值:
func convertBoundingBox(_ box: CGRect, in imageSize: CGSize) -> CGRect {
// Vision坐标:原点在左下角,归一化值
// UIKit坐标:原点在左上角,像素值
let x = box.origin.x * imageSize.width
let height = box.height * imageSize.height
let y = (1 - box.origin.y - box.height) * imageSize.height
let width = box.width * imageSize.width
return CGRect(x: x, y: y, width: width, height: height)
}
// 结合图片方向获取真实尺寸
func imageSize(for image: UIImage) -> CGSize {
guard let cgImage = image.cgImage else { return .zero }
// 图片可能有EXIF旋转信息,需按方向修正
if image.imageOrientation == .left || image.imageOrientation == .right {
return CGSize(width: cgImage.height, height: cgImage.width)
}
return CGSize(width: cgImage.width, height: cgImage.height)
}
需要特别注意EXIF方向问题。用相机拍摄的图片往往带有方向元数据,UIImage会自动应用方向,而Vision处理的是原始CGImage数据,两者坐标系可能相差90度或180度。解决办法要么在识别前把图片重绘为正向图片,要么像上面代码那样根据imageOrientation交换宽高后再换算坐标。
换算完成后,就可以用CALayer或CAShapeLayer在图片上绘制识别框,下面是一个完整的视图叠加示例:
func drawResultBoxes(observations: [VNRecognizedTextObservation],
on imageView: UIImageView,
imageSize: CGSize) {
imageView.layer.sublayers?.forEach { $0.removeFromSuperlayer() }
let scale = imageView.bounds.size.width / imageSize.width
for observation in observations {
let converted = convertBoundingBox(observation.boundingBox, in: imageSize)
let boxLayer = CAShapeLayer()
boxLayer.frame = CGRect(
x: converted.origin.x * scale,
y: converted.origin.y * scale,
width: converted.width * scale,
height: converted.height * scale
)
boxLayer.borderWidth = 2
boxLayer.borderColor = UIColor.systemRed.cgColor
imageView.layer.addSublayer(boxLayer)
}
}
四、提升识别准确率的实用建议
实际项目中,识别准确率往往受图片质量影响最大。图片模糊、文字过小、背景复杂都会导致结果变差。建议在识别前对图片做适当预处理,例如用Core Image的CIColorControls提升对比度,或者对过小的文字区域先放大再识别。
对于长图或分辨率很高的图片,一次性识别整张图可能遗漏小字。更好的做法是结合VNDetectTextRectanglesRequest先粗定位文字区域,再裁剪出子图分别识别,能显著提升小字场景的召回率。另外,尽量使用.accurate模式处理静态图片,只在实时取景这种对性能敏感的场景使用.fast模式。
最后关于系统版本兼容:精确模式和主要语言支持需要iOS 13以上,韩文支持需要iOS 14以上,而部分扩展语言(如俄文、阿拉伯文)需要iOS 16以上。如果项目要兼容更低系统版本,可以通过#available做判断,降级到只支持英文的识别,或者引导用户升级系统获得完整的多语言能力。
总结来说,Vision Framework提供了完全本地化、免费且保护隐私的OCR方案,配合坐标提取能力可以胜任绝大多数文字识别需求。掌握语言配置和坐标转换这两个核心难点后,再结合业务场景做针对性优化,就能打造出体验良好的文字识别功能。
Vision FrameworkiOS OCR文字识别修改时间:2026-08-31 07:10:32