Highlight
VisionKit 在 iOS 17 和 macOS Sonoma 中新增了 Subject Lifting(主体提取)和 Visual Look Up(视觉查找)两项核心能力,DataScannerViewController 增加了光学流追踪和货币识别,macOS 原生 App 可以通过 ImageAnalysisOverlayView 集成 Live Text、Subject Lifting 和 Visual Look Up,且大部分功能对已接入图像分析 API 的 App 自动生效、无需代码改动。
核心内容
问题:图片中的信息难以直接利用
用户在 App 中看到一张图片,想提取其中的文字、识别图中的物体、或者把某个主体单独拿出来分享。传统做法需要开发者自己集成复杂的计算机视觉模型,处理不同场景的边缘情况。
VisionKit 在 WWDC22 引入了 Live Text 和 DataScanner,让这些问题有了系统级解决方案。WWDC23 在此基础上扩展了三项能力:
- Subject Lifting:长按提取图片中的主体,支持创建贴纸
- Visual Look Up:识别宠物、植物、地标、艺术品等,新增食物、产品和标志符号
- macOS 原生支持:Catalyst 和原生 macOS App 都可以使用 VisionKit
详细内容
Subject Lifting 自动可用(01:13)
如果你已经在使用 VisionKit 的图像分析 API,Subject Lifting 已经自动启用:
import VisionKit
let analyzer = ImageAnalyzer()
let interaction = ImageAnalysisInteraction()
// 分析图像
let configuration = ImageAnalyzer.Configuration([
.text,
.machineReadableCodes
])
let analysis = try? await analyzer.analyze(image, configuration: configuration)
interaction.analysis = analysis
imageView.addInteraction(interaction)
关键点:
- 不需要修改现有代码,Subject Lifting 自动生效
- 分析配置中不需要添加特殊参数
- Subject Lifting 的分析在初始分析完成后延迟执行,节省电量
- iOS 上在图片显示几秒后触发,macOS 上在首次显示菜单时触发
控制交互类型(02:38)
// 仅启用 Subject Lifting,不包含文本选择
interaction.preferredInteractionTypes = .imageSegmentation
// 组合多种交互类型
interaction.preferredInteractionTypes = [.imageSegmentation, .textSelection]
// 保持 iOS 16 的自动行为(文本 + 二维码,不含 Subject Lifting)
interaction.preferredInteractionTypes = .automaticTextOnly
// 默认:包含所有功能
interaction.preferredInteractionTypes = .automatic
关键点:
.automatic包含文本选择、Subject Lifting、数据检测器等所有功能.imageSegmentation只启用主体提取.automaticTextOnly保持 iOS 16 的行为,不包含 Subject Lifting- 可以用数组组合多种类型
Visual Look Up(03:23)
Visual Look Up 支持识别以下类别:
- 原有类别:宠物、自然(植物/花卉)、地标、艺术品、媒体
- iOS 17 新增:食物、产品、标志和符号
启用 Visual Look Up 需要在分析配置中添加 .visualLookUp:
let configuration = ImageAnalyzer.Configuration([
.text,
.visualLookUp
])
let analysis = try? await analyzer.analyze(image, configuration: configuration)
interaction.analysis = analysis
关键点:
- Visual Look Up 的处理分为两个阶段
- 第一阶段完全在设备上完成:定位结果边界框、确定顶级类别(如猫、书、植物)、提取特征
- 第二阶段仅在用户请求时联网:将类别和图像嵌入发送到服务器获取详细信息
- 隐私保护:设备只发送特征嵌入,不发送原始图像
Visual Look Up 的两种交互模式(04:40)
模式一:与 Subject Lifting 联动
如果提取的主体恰好只有一个关联的 Visual Look Up 结果,菜单中会显示 “Look Up” 选项。VisionKit 自动处理这个交互。
模式二:模态徽章模式
// 将 Visual Look Up 设为首选交互类型
interaction.preferredInteractionTypes = .visualLookUp
关键点:
- 图片上会显示徽章标记每个视觉搜索结果
- 徽章在移出视口时会自动移到角落
- 用户点击徽章查看 Look Up 结果
- 这种模式会覆盖其他交互类型(不能同时选中文本)
- 通常配合按钮使用,让用户主动进入/退出此模式
DataScannerViewController 增强(06:03)
光学流追踪:让实时摄像头中的文字高亮更加稳定。
let scanner = DataScannerViewController(
recognizedDataTypes: [.text()],
qualityLevel: .balanced,
recognizesMultipleItems: true,
isHighFrameRateTrackingEnabled: true // 默认已启用
)
关键点:
- 光学流追踪自动启用,无需额外代码
- 仅在识别文本时可用,不适用于二维码
- 需要不指定具体的文本内容类型
highFrameRateTracking默认开启
货币识别:
let scanner = DataScannerViewController(
recognizedDataTypes: [
.text(textContentType: .currency)
]
)
// 处理识别结果
for await item in scanner.recognizedItems {
if case .text(let text) = item {
let transcript = text.transcript // 例如 "$12.99"
// transcript 包含货币符号和金额
}
}
关键点:
textContentType: .currency启用货币识别- 识别结果包含货币符号和金额文本
- 可以结合当前 locale 解析具体的货币值
Live Text 增强(08:27)
新增语言支持:泰语和越南语。
表格检测:Live Text 现在支持检测和提取图片中的表格结构。
// 用户选中表格区域后复制
// 粘贴到 Numbers 或 Notes 时,表格结构自动保留
// 包括单元格合并等复杂结构
上下文感知数据检测器:
当用户从图片中添加联系人时,系统会自动提取周围相关的数据检测器信息(如电话号码、地址),一并填入联系人卡片。
新的文本选择 API(10:04)
// 获取选中的纯文本
let selectedText = interaction.selectedText
// 获取带属性的文本
let selectedAttributedText = interaction.selectedAttributedText
// 获取选中的范围
let selectedRange = interaction.selectedRange
// 监听选择变化
func imageAnalysisInteraction(
_ interaction: ImageAnalysisInteraction,
didUpdateSelectionWithText selectedText: String?
) {
// 更新 UI,例如启用/禁用自定义菜单项
}
关键点:
selectedText返回纯文本字符串selectedAttributedText返回带格式的 NSAttributedStringselectedRange返回在分析文本中的范围- 新的 delegate 方法在选择变化时回调
自定义菜单(10:31)
override func buildMenu(with builder: UIMenuBuilder) {
super.buildMenu(with: builder)
// 获取当前选中的文本
guard let selectedText = interaction.selectedText,
!selectedText.isEmpty else { return }
// 创建自定义命令
let createReminderAction = UIAction(title: "Create Reminder") { _ in
// 用选中的文本创建提醒事项
self.createReminder(with: selectedText)
}
// 创建菜单
let reminderMenu = UIMenu(title: "", children: [createReminderAction])
// 插入到系统菜单之后
builder.insertSibling(reminderMenu, afterMenu: .share)
}
关键点:
- 使用
UIMenuBuilderAPI 插入自定义菜单项 - 可以基于当前选中的文本动态创建菜单
- 自定义菜单与系统菜单(复制、分享等)并排显示
macOS Catalyst 支持(11:08)
Catalyst App 只需重新编译即可获得 VisionKit 支持:
- 支持 Live Text、Subject Lifting、Visual Look Up
- 不支持二维码扫描(
.machineReadableCodes在 Catalyst 上为 no-op) - 保留
.machineReadableCodes在配置中是安全的,不会报错
macOS 原生 API:ImageAnalysisOverlayView(12:14)
原生 macOS App 使用 ImageAnalysisOverlayView:
import VisionKit
// 分析图像(与 iOS 相同)
let analyzer = ImageAnalyzer()
let configuration = ImageAnalyzer.Configuration([.text, .visualLookUp])
let analysis = try? await analyzer.analyze(image, configuration: configuration)
// 创建叠加视图
let overlayView = ImageAnalysisOverlayView()
overlayView.analysis = analysis
// 添加到视图层级
imageView.addSubview(overlayView)
// 如果使用 NSImageView,设置 trackingImageView 自动计算 contentsRect
overlayView.trackingImageView = imageView
// 如果不使用 NSImageView,手动提供 contentsRect
extension ViewController: ImageAnalysisOverlayViewDelegate {
func contentsRect(for overlayView: ImageAnalysisOverlayView) -> CGRect {
// 返回图像内容在 overlayView 坐标系中的位置
return imageContentRect
}
}
关键点:
ImageAnalysisOverlayView是NSView的子类- 需要添加到图像内容之上
trackingImageView属性自动处理contentsRect计算contentsRect使用单位坐标系(左上角为原点)
macOS 上下文菜单集成(15:13)
extension ViewController: ImageAnalysisOverlayViewDelegate {
func overlayView(
_ overlayView: ImageAnalysisOverlayView,
updatedMenu menu: NSMenu,
for event: NSEvent,
at point: CGPoint
) -> NSMenu {
// 获取 VisionKit 菜单项
let copySubjectItem = menu.item(withTag: ImageAnalysisOverlayView.MenuItemTag.copySubject.rawValue)
// 添加到自己的菜单中
let myMenu = NSMenu()
myMenu.addItem(copySubjectItem!)
// 或者修改菜单项标题
copySubjectItem?.title = "Copy Photo"
// 或者将自定义项插入 VisionKit 菜单
let myItem = NSMenuItem(title: "My Custom Action", action: #selector(customAction), keyEquivalent: "")
if let recommendedIndex = menu.indexOfItem(withTag: ImageAnalysisOverlayView.MenuItemTag.recommendedAppItems.rawValue) {
menu.insertItem(myItem, at: recommendedIndex)
}
return menu
}
}
关键点:
updatedMenu:forEvent:atPoint:允许你修改或替换右键菜单- VisionKit 菜单项通过
MenuItemTag标识 recommendedAppItems标签标识了推荐插入自定义项的位置- 菜单项每次都会重新创建,可以安全修改属性
- VisionKit 会自动处理菜单高亮时的主体提取动画
核心启发
-
为相册 App 添加一键主体提取分享:如果你的 App 显示图片,将
ImageAnalysisInteraction的preferredInteractionTypes设为.automatic,用户长按即可提取主体并分享。为什么值得做:主体提取是 iOS 17 的标志性功能,用户已经熟悉这个交互。你的 App 支持后,用户体验与系统 Photos app 一致。怎么开始:确认已有图像分析代码,将preferredInteractionTypes从.automaticTextOnly改为.automatic。 -
为购物 App 集成 Visual Look Up:在商品图片上启用 Visual Look Up,让用户识别产品并获取更多信息。为什么值得做:Visual Look Up 支持产品识别,用户可以直接从图片中了解商品详情,减少搜索步骤。怎么开始:在
ImageAnalyzer.Configuration中添加.visualLookUp,设置preferredInteractionTypes = .visualLookUp配合按钮进入徽章模式。 -
为记账 App 添加收据扫描:用 DataScannerViewController 的货币识别功能,自动提取收据上的金额并汇总。为什么值得做:手动输入收据金额繁琐且容易出错。DataScanner 可以实时识别货币值,结合光学流追踪,高亮稳定不抖动。怎么开始:创建
DataScannerViewController,设置recognizedDataTypes为.text(textContentType: .currency),在recognizedItems流中累加金额。 -
为 macOS 图片编辑器添加 Live Text:用
ImageAnalysisOverlayView让 macOS App 支持图片中的文本选择和复制。为什么值得做:macOS 用户习惯右键菜单操作,Live Text 让图片中的文字可以直接编辑,无需 OCR 预处理。怎么开始:创建ImageAnalysisOverlayView,设置为imageView的子视图,设置trackingImageView属性,实现overlayView:updatedMenu:forEvent:atPoint:delegate 方法自定义菜单。
关联 Session
- Lift subjects from images in your app — Subject Lifting 的底层 Vision 框架实现和高级用法
- Discover machine learning enhancements in Create ML — 训练自定义图像理解模型,与 VisionKit 互补
- Detect animal poses in Vision — Vision 框架的动物姿态检测,适合与 VisionKit 结合使用
评论
GitHub Issues · utterances