一、功能简介
本篇将实现一个完整的 AI 图像识别流程:用户上传图片 → 上传至后端 AI 接口 → 接收识别结果(如检测框、分类标签)→ 在页面进行图文标注展示。适用于智能识图、商品识别、人脸检测、图像审核等场景。
二、核心流程架构
[上传图片] → [后端AI识别接口] → [返回结果(JSON)] → [前端绘制标注]
三、技术模块说明
模块 | 功能 | 技术实现 |
---|---|---|
文件选择器 | 上传图片 | filePicker |
文件读取 | 获取图片 Buffer | fs + util |
AI 接口通信 | 发起 POST 请求 | http.request() |
标注渲染 | 绘制检测框、标签 | Canvas 或 WebView + HTML5 Canvas |
四、HTML 标注页面(resources/rawfile/ai_result_canvas.html)
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>AI 识别结果</title></head>
<body style="margin:0">
<canvas id="canvas"></canvas>
<script>
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
window.addEventListener('message', (e) => {
const { imageBase64, results } = JSON.parse(e.data)
const img = new Image()
img.src = imageBase64
img.onload = () => {
canvas.width = img.width
canvas.height = img.height
ctx.drawImage(img, 0, 0)
results.forEach(obj => {
const [x, y, w, h] = obj.bbox
ctx.strokeStyle = 'red'
ctx.lineWidth = 2
ctx.strokeRect(x, y, w, h)
ctx.font = '14px sans-serif'
ctx.fillStyle = 'red'
ctx.fillText(obj.label, x, y - 5)
})
}
})
</script>
</body>
</html>
五、ArkTS 页面(AiImageLabelDemo.ets)
import filePicker from '@ohos.file.picker'
import fs from '@ohos.file.fs'
import http from '@ohos.net.http'
import util from '@ohos.util'
@Entry
@Component
struct AiImageLabelDemo {
@State base64Image: string = ''
@State webController: WebController | undefined
@State message: string = ''
async pickImageAndRecognize() {
try {
const picker = new filePicker.FilePicker()
const result = await picker.pickFiles({
type: ['image/*'],
maxSelectNumber: 1
})
if (result.length === 0) {
this.message = '⚠️ 未选择图片'
return
}
const fd = await fs.open(result[0].uri)
const stat = await fs.stat(fd)
const buffer = await fs.read(fd, { length: stat.size })
await fs.close(fd)
const base64 = util.encodeToString(buffer, 'base64')
this.base64Image = `data:image/jpeg;base64,${base64}`
this.message = '📤 上传中...'
const res = await http.createHttp().request('https://mockapi.ai/recognize', {
method: http.RequestMethod.POST,
header: { 'Content-Type': 'application/json' },
extraData: JSON.stringify({ imageBase64: base64 })
})
if (res.responseCode === 200) {
const json = JSON.parse(res.result.toString())
this.webController?.postMessage(JSON.stringify({
imageBase64: this.base64Image,
results: json.objects || []
}))
this.message = `✅ 识别完成,检测到 ${json.objects.length} 个目标`
} else {
this.message = '❌ 识别失败'
}
} catch (e) {
this.message = '❌ 异常:' + JSON.stringify(e)
}
}
build() {
Column() {
Text('AI 图像识别与标注渲染')
.fontSize(20)
.margin({ bottom: 16 })
Button('📷 上传图片识别')
.onClick(() => this.pickImageAndRecognize())
.margin({ bottom: 12 })
Text(this.message)
.fontSize(14)
.fontColor(this.message.includes('✅') ? Color.Green : Color.Red)
Web({
src: 'rawfile:///ai_result_canvas.html',
controller: ctrl => this.webController = ctrl
})
.width('100%')
.height(360)
.margin({ top: 16 })
}
.width('100%')
.padding(20)
}
}
六、运行效果说明
-
上传一张图片;
-
系统将图片编码为 Base64,并 POST 给 AI 接口;
-
接收返回格式如:
{
"objects": [
{ "label": "猫", "bbox": [120, 80, 160, 140] },
{ "label": "狗", "bbox": [300, 120, 130, 110] }
]
}
-
WebView Canvas 绘制识别框 + 类别文字。
七、常见问题与优化建议
问题 | 表现 | 原因 | 建议 |
---|---|---|---|
无结果 | 空标注 | 模型未识别 | 增加提示或重试按钮 |
图片过大 | 加载慢 | Base64 编码过长 | 建议压缩图像或缩放上传 |
渲染异常 | 框位置不对 | bbox 比例不符 | 坐标需相对图片尺寸预处理 |
八、拓展建议
-
接入 OCR(文字识别)模型 → 绘制文字框;
-
实现检测后编辑框位置和标签;
-
增加识别记录本地缓存;
-
搭配第51~56篇实现:导入→识别→导出分析报告一体化流程;
-
分布式支持:手机识别,平板上标注呈现。