我之前做图片类功能时,曾经想过开发一个轻量级的纸质资料扫描工具。需求很简单:用户把纸放在桌面上拍照,应用就能把它整理成适合阅读和保存的电子资料。
但真正拆解需求后,我发现,普通拍照和文档扫描之间还有不少差距。
普通拍照关注的是把眼前的画面记录下来;文档扫描则更关心纸张边界、页面区域、透视变形和最终文档的可读性。
HarmonyOS 7 的 Vision Kit 提供了文档扫描等场景化视觉能力,可以帮助开发者减少从零实现视觉处理流程的工作量。
先把扫描流程拆成几个环节。我会把整个功能拆成图片采集、文档区域识别、页面校正、结果预览和文件保存。
其中,文档区域识别与页面校正应该尽可能交给适合的扫描能力处理;应用层则负责组织交互、管理扫描结果和完成文件保存。
为了让业务层不依赖具体的视觉服务,我会先定义扫描结果:
interface ScanPage {
uri: string;
width: number;
height: number;
}
interface ScanDocument {
pages: ScanPage[];
createdAt: number;
}
function validateScan(
document: ScanDocument
): boolean {
if (document.pages.length === 0) {
return false;
}
return document.pages.every(
(page: ScanPage) => {
return page.uri.length > 0 &&
page.width > 0 &&
page.height > 0;
}
);
}
这里的 uri、宽高和创建时间是我为业务层设计的字段,并不是官方文档扫描服务保证返回的原生数据结构。正式接入时,需要根据实际接口完成数据映射。
为什么我建议增加扫描预览?
如果用户扫描的是一张会议记录,结果不完整可能只是少了一行字;如果扫描的是合同或票据,漏掉一个数字就可能影响后续使用。
因此,我不会在扫描完成后立即保存并退出,而是先展示预览,让用户检查边缘是否完整、页面是否倾斜,以及文字是否清晰。
对于多页文档,还需要提供删除某一页、调整顺序和重新扫描的能力。
页面代码可以先这样设计
@Entry
@Component
struct ScanPreviewPage {
@State pageCount: number = 0;
@State status: string = '等待扫描';
build() {
Column({ space: 16 }) {
Text('文档扫描')
.fontSize(24)
.fontWeight(FontWeight.Bold)
Text(this.status)
.fontSize(16)
Text(`当前页数:${this.pageCount}`)
Button('开始扫描')
.onClick(() => {
this.status = '等待接入文档扫描服务';
})
Button('清空扫描记录')
.onClick(() => {
this.pageCount = 0;
this.status = '等待扫描';
})
}
.padding(20)
.width('100%')
}
}
这只是界面骨架,不会真正启动扫描。后续需要把按钮连接到官方支持的扫描流程,并处理权限、取消和异常返回。
扫描完成后,还有一段工作。需要进一步考虑文档保存格式、文件命名、重复文件管理和用户再次打开时的体验。
如果业务需要搜索文档内容,可以在扫描完成后继续接入 OCR;如果需要归档,还可以结合关键词提取和分类功能。
不过,不要把所有步骤都塞进一个按钮里。扫描、识别、分类和保存分别承担不同任务,拆分后更容易定位问题,也便于未来替换某项能力。
在我看来,文档扫描最值得开发者关注的,不是如何把摄像头画面显示出来,而是如何把一张不规整的纸质照片,变成用户愿意长期保存和使用的数字文档。
相关推荐
鸽芷咕
93
0
KevinChaos
70
0
阿川写界面
319
0
codezi
147
0马上去coding
我还没有写个人简介......
帖子
提问
粉丝
聊聊HarmonyOS Agent智能体的架构:从"能聊天"到"能干活" #向光而行 码向未来
2026-10-19 21:33:46 发布Fedora 45 Beta发布:kmscon把Linux控制台带入21世纪
2026-09-17 12:17:50 发布


京公网安备:11010502051901号