android: revert image to locked orientation (user decision); keep official-style manual rotate/flip settings

This commit is contained in:
ZXCLI
2026-09-11 03:50:56 +08:00
parent 464cfcb5e8
commit f7bca894ba
13 changed files with 227 additions and 218 deletions
+20 -18
View File
@@ -67,7 +67,7 @@ android/app/src/main/kotlin/com/mag160c/thermal/
│ │ +底部快门区(相册/拍照/录像)+SurfaceView+PIP浮层
│ ├─ PipCameraView.kt 可见光PIP相机引擎(Camera2最小实现,异常只记日志)
│ ├─ ImageTransform.kt 方向/翻转/letterbox/缩放几何 + 传感器↔屏幕互逆映射(纯 Kotlin,单测覆盖)
│ └─ LiveRenderer.kt SurfaceView 软件渲染:图像按握持角补偿旋转(rot=90-φ)、
│ └─ LiveRenderer.kt SurfaceView 软件渲染:图像锁定竖屏框架(90°,可按设置手工旋转/翻转)、
│ letterbox+变倍、色标条/圆环标记/中心温OSD(标签按旋转包围盒定位)
├─ ui/gallery/ 相册页(MediaStore DCIM/MAG160C 扫描 + 内嵌JPEG缩略图 + 运行时媒体权限)
├─ ui/analyze/ MDT 离线分析(缩放/调色板重渲染/温度条+点击测温/备注回写/PDF报告)
@@ -130,28 +130,30 @@ res/drawable/*.xml 自绘矢量图标(双弧圆等可靠几何图形
- 旧 analysis/protocol_spec.md 的 66f/670 描述("prepare/version query")不准,
以 magcx_official_flow.md 为准。
### 4.3 实时画面渲染(2026-09-11 修订:图像内容随握持朝向补偿
### 4.3 实时画面渲染(2026-09-11 定稿:图像锁定 + 官方同款手工修正
- **Activity 锁定竖屏**manifest `screenOrientation="portrait"`):屏幕相对手机框架
永不旋转。顶栏、热像区域、底栏的**绝对位置**永远贴着手机竖屏的物理顶边(挖孔侧)、
中间、物理底边;手机怎么物理旋转,构图都不动。**不要改回 fullSensor。**
- **图像内容补偿旋转(本轮修订,勿回退)**:构图不动,但**画面内容**必须随握持朝向
反向补偿,否则转身后场景跟着转、与镜头实际指向脱节。规则:
`rot = 90 - φ`(φ = DeviceOrientation 握持角 0/90/180/270)。
依据官方实现:`MainActivity.windowOrientationListener` 把 Display.rotation
(0/1/2/3) 映射成图像 90/0/270/180,再经 `ImageViewer.drawImage` 的
`matrix.postRotate` 应用;官方**窗口会随传感器旋转**,故可见结果恒为 90
我们锁了窗口,图像就要承担全部差值 → `90 - φ`。
显示旋转索引→角度约定取自官方自家相机代码
`VisibleCameraHelper.setPreviewOrientation`case 0→0/1→90/2→180/3→270
即索引 N = 顺时针 N×90)。
- **手工修正项**(官方"旋转USB画面/水平翻转/竖直翻转"同款):设置页三项,
叠加在自动补偿之上,持久化于 `AppSettings.imageRotateDeg/imageFlipH/imageFlipV`
用于传感器安装方向特殊的机器。翻转在像素拷贝阶段完成,保证几何映射可测。
- **图像内容同样锁定**(用户 2026-09-11 明确)**,不随握持角旋转**:热像传感器
物理装在手机上、跟着手机一起转,所以锁定图像时场景与世界的相对方向自动保持
正确,**不需要**加速度计参与。这也正是官方 App 的屏上效果(官方窗口随传感器
转,其面板级图像旋转因此是恒定的 90°)。
- ⚠️ **曾经改错又改回**:2026-09-11 中途有一版把图像按握持角反向补偿
`rot = 90 - φ`),结果**双重补偿**,正是用户报的"右转画面往反方向转"
**不要再引入握持角参与图像旋转。**
- `ImageTransform.params()` **不接受握持角参数**——这是编译期保证。
- **手工修正项**(官方"旋转USB画面/水平翻转/竖直翻转"同款,设置页):
`imageRotateDeg`(0/90/180/270) 叠加在锁定基准 90° 之上;两个翻转作用在
**传感器帧**上(与官方一致:翻转交给 native,旋转在显示矩阵上)。
持久化于 `AppSettings`
- **数学等价关系(单测锁定)**:**"竖直翻转 + 旋转 90°" ≡ "水平翻转 + 旋转 270°"**
(逐像素比对验证)。用户实测"竖直翻转 + 旋转 90°"可把画面转到另一方向,
正是这条恒等式;两者只差一次水平镜像。
- **图标/文字按握持角补偿**`graphicsLayer rotationZ=-φ`Compose/
`canvas.rotate(-φ)`(Canvas)。**标签一律按旋转后包围盒定位**
`ImageTransform.rotatedBoxHalfExtents` + `drawGripText`),不要再拿基线锚点
摆位——色标条两端数字曾因此与色条错位。
`canvas.rotate(-φ)`Canvas,保证任何握持姿态下可读。**标签一律按旋转后
包围盒定位**`ImageTransform.rotatedBoxHalfExtents` + `drawGripText`),
不要再拿基线锚点摆位——色标条两端数字曾因此与色条错位。
- **几何单一来源**`ui/live/ImageTransform.kt`(纯 Kotlin,可单测)同时供
渲染器与点击/探针映射使用(`sensorToScreen` / `screenToSensor` 互为逆映射,
已对 0/90/180/270 × 翻转组合做往返测试)。渲染与取温映射**必须**用同一套参数,