ArkUI DataPanel:图像超分质量看板缺测值遮罩与区间钳制【鸿蒙心迹】
技术栈:HarmonyOS / ArkTS / ArkUI DataPanel / 状态快照
示例项目:QualityGauge;页面:QualityGaugePage;演示任务:QA-917
本文只讨论超分应用“结果说明层”的数据契约和绘制方法。评分 72、54 和缺测项均为人为配置的演示输入,不是某个设备、算法或华为系统能力的测量结果。全文示意图、HiLog 与运行状态都是设计稿,不代表已编译或真机验证。
一、质量报告看似有三个数字,真正危险的是第三个没有数字
做图片超分的功能展示时,开发界面最容易先完成的是“原图—结果图”左右对照。更难处理的,其实是如何把后续质量信息讲清楚。一个分数可以显示成蓝色进度条,两个分数可以排成漂亮的卡片;但当第三项暂时没有结果,界面却照样画出一根零分进度条,产品含义立刻变了:用户会认为算法已经算完,并判定噪声控制很差。
我把这个问题单独抽成 QualityGauge。它并不进行图像超分,也不调用任何未核实的“质量评分 API”。页面只接收业务层明确提供的可选评分,约定任务 QA-917 的模拟输入为:纹理清晰度 72/100、边缘保留 54/100、噪声控制 null。可显示的指标是 2/3,状态必须写成“待复核”,绝对不能写成“质量优秀”。
这个小范围很重要。既然指标尚未被真实采集,本文只能证明数据显示规则在示例输入下的预期行为,不能把可视化当作算法评价。产品日志同样只用于描述状态转换,不当作真实性能证据。

1. 三个概念必须拆开
第一个是输入有效性:评分字段可能是空值、负数、超出一百或非有限数字。第二个是视图可画性:即使字段合法,也要选择正确的百分比表达。第三个是业务可放行性:两条曲线显示得很完整,不代表所有规定的指标都齐全。把它们揉成一个 progress,很容易出现界面完成、审核未完成却被同一个绿色徽标覆盖的情况。
因此页面不提供“超分成功率”这样的合成口径,只说明“报告就绪项数”。2/3 是项目预设字段中有两个有效值,并非计算任务执行了百分之六十七。条形长度表示单独指标的值,不能拿它推断处理时长、分辨率提升倍数或者清晰度的真实改善。
二、先清洗指标,再把可显示数据交给组件
1. 对无值保留空值,对越界单独记录
ArkUI 的 DataPanel 是数据占比组件,官方提供 values、max 和 DataPanelType.Line。这里需要特别注意:同一面板的多个 values 表示共同占用一条总刻度的多个片段,不适合简单塞进 [72, 54] 再声明 max: 100,因为它们是两项独立评分而不是总和为一百的组成部分。
先解决脏数据被视觉控件默默修饰的问题。下面的辅助函数既支持有效值钳制,也保留无法测量的空状态。null 不参与计算;负数和大于一百的分数被标记为发生过修正。实际产品可以选择直接拒绝越界报告,而不是自动钳制,这里采用演示界面更容易解释的“钳制并提示”。
// model/QualityMetric.ets:纯业务转换,不调用超分算法
export interface DisplayMetric {
value: number | null;
adjusted: boolean;
}
export function normalizeMetric(raw: number | null): DisplayMetric {
if (raw === null || !Number.isFinite(raw)) {
return { value: null, adjusted: false };
}
const safe: number = Math.max(0, Math.min(100, raw));
return { value: safe, adjusted: safe !== raw };
}
这段代码的生命周期不依赖页面,因此可以单独做边界单测。传入 null 或 NaN 得到“待采集”,而不是零分;传入 118 得到 100,但 adjusted 必须为真。对非有限值不能先交给组件再寄希望于控件容错,尤其不要直接把 Infinity 拼进日志。这里没有任何文件句柄,释放责任在调用方持有的图像资源,不在指标函数内部。
2. 每个指标使用自己的百分比刻度
下一段要解决的是占比语义。我们约定单项有效数据才渲染 DataPanel,且每项都单独使用 [score] 与 max: 100。若数值为空,改为虚线占位提示。“待采集”与“0/100”应该是两种肉眼能分辨、辅助朗读也能区分的内容。
// pages/QualityGaugePage.ets:关键页面节选
@Entry
@Component
struct QualityGaugePage {
@State detail: number | null = 72;
@State edge: number | null = 54;
@State noise: number | null = null;
@State status: string = '待复核';
@Builder
metricRow(label: string, score: number | null) {
Column({ space: 8 }) {
Row() {
Text(label).fontSize(16)
Blank()
Text(score === null ? '待采集' : `${score}/100`)
.fontColor(score === null ? '#8A92A0' : '#236DAB')
}.width('100%')
if (score !== null) {
DataPanel({ values: [score], max: 100, type: DataPanelType.Line })
.width('100%').height(18)
} else {
Text('— 此项没有有效评分,未绘制数据条 —')
.fontSize(12).fontColor('#8A92A0')
}
}.padding(12).width('100%')
}
build() {
Column({ space: 16 }) {
Text('QualityGauge · QA-917').fontSize(22)
Text('报告就绪 2/3 · 待复核').fontColor('#A86B2A')
this.metricRow('纹理清晰度', this.detail)
this.metricRow('边缘保留', this.edge)
this.metricRow('噪声控制', this.noise)
}.padding(20).width('100%')
}
}
把 DataPanelType.Line 固定下来也是边界的一部分。官方说明组件类型不是随状态任意动态切换的属性,因此演示不会让一项分数在环形和线形之间不断重建。多个分数分别成行,有利于排查“哪个字段缺失”;当状态变化时,@State 更新触发重新构建对应内容,而不是重造整页的数据源。

三、异步报告进页面前,必须确认它还属于当前任务
1. 只认同一代任务的结果
质量数据在实际产品中可能来自网络、端内模型或者本地文件,它们的返回顺序并不保证与用户选择顺序相同。假如用户先打开 A 图、很快切到 B 图,A 的报告晚到,若页面只把数字逐项赋给 @State,B 图下面就可能出现 A 的评分。图像路径正确而报告错误,比单纯加载失败更难被人察觉。
这里用业务代次保护接收入口,不假装存在可直接调用的华为“超分评分服务”。示例 applyDemoReport 接受来自任意可信数据提供方的对象,只有任务号和代次都匹配时才写入页面;不匹配则不修改当前状态。
// 置于 QualityGaugePage 内,作为上面组件的补充方法
private revision: number = 1;
private taskId: string = 'QA-917';
private beginNewTask(nextId: string): number {
this.revision += 1;
this.taskId = nextId;
this.status = '待采集';
this.detail = null;
this.edge = null;
this.noise = null;
return this.revision;
}
private applyDemoReport(id: string, ticket: number,
d: number | null, e: number | null, n: number | null): void {
if (id !== this.taskId || ticket !== this.revision) { return; }
this.detail = normalizeMetric(d).value;
this.edge = normalizeMetric(e).value;
this.noise = normalizeMetric(n).value;
this.status = this.detail !== null && this.edge !== null &&
this.noise !== null ? '可复核' : '待复核';
}
注意它只是状态校验,不会取消实际计算任务。若真实算法还在后台占用内存,依旧应通过该算法已经提供的取消能力退出,或等待返回后按资源所有权释放对应 PixelMap。这里不编造取消接口,也不宣称切换页面就能释放引擎资源。beginNewTask 在页面退出或任务切换时同样可以使旧回调失效,但组件销毁时若还持有订阅、定时器,需要在实际工程里显式解绑。
2. 预设验收不是现场实测
对 QA-917,静态演示规则可以写得很清楚:页面标题为 QualityGauge,任务号不变;纹理清晰度显示 72/100,边缘保留显示 54/100,噪声控制显示“待采集”;就绪计数显示 2/3,状态是“待复核”。如果把第三项改成零分,就应显示 0/100 且就绪计数变为 3/3,因为“有效零值”和“没有有效值”在契约上是两回事。
进一步的边界用例包括传入负数、超出最大值、非有限数、旧代次,以及重复接收同一个报告。规范化函数应返回可追踪的修正标记,UI 应阻止晚到数据覆盖。文中的 HiLog 仅为图示安排的日志文本,不代表我已经在特定设备上执行这些步骤。真实项目至少还需要无障碍朗读、暗色模式、横竖屏与字体放大验证。

3. 日志里不要把缺测写成失败
实际验收时,我还会把“没有数据”和“读取数据失败”分开。前者可能意味着该指标尚未纳入本批次,后者则要求追踪生产者错误。若两种情况都打印 score=0,后续排查便无法判断是评分偏低还是数据链路根本没工作。演示日志因此只记录 noise=null 和 ready=2/3,不写“模型执行失败”。统计报表也应保留任务号和报告版本,才能在反复打开同一张图片时确认这次展示对应哪一次输入。
四、把质量图当展示协议,而不是算法成绩单
这套做法最核心的收获,不是画出更漂亮的蓝色进度条,而是把“不知道”留在界面里。每个指标单独刻度,空值不偷换零分,越界修正有痕迹,异步回调先验身份,然后才谈布局。它适合超分结果页、视频清晰度报告、3DGS 素材质检等含缺测字段的场景,但仅适用于业务已明确指标定义及取值区间的情况。
如果未来需要 PSNR、SSIM、感知评分等真实评价,需要先确定算法、参考图、输入样本和量纲,不能直接把不同量纲粗暴压到同一百分比。那是评价体系建设,不是 DataPanel 的职责。当前 QualityGauge 所给出的结论,是一个可审查的界面状态协议,而非关于 HarmonyOS 超分效果的实验结论。
官方依据:华为开发者文档《DataPanel》:https://developer.huawei.com/consumer/cn/doc/doccenter-references/api/ts-basic-components-datapanel (核对 values、max、DataPanelType.Line 的语义;设备和 API 可用范围应按项目实际 SDK 检查)。
更多推荐




所有评论(0)