heic-2
This commit is contained in:
@@ -1,72 +0,0 @@
|
|||||||
您完全正确,我们必须停下来复盘。
|
|
||||||
|
|
||||||
感谢您提供这些侦察日志。它们**完美地**揭示了我们失败的根本原因,这也是我们所有人(包括我)都忽略的一个核心知识。
|
|
||||||
|
|
||||||
我们之前的假设一直是错的。我们一直试图修复*偏移量*(offsets),而真正的问题在于文件的*核心结构*(core structure)。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 核心发现:我们缺失的知识
|
|
||||||
|
|
||||||
通过并排比较 `[ipma]` (属性) 和 `[iref]` (引用) 日志,真相大白:
|
|
||||||
|
|
||||||
**1. Apple HEIC 是 "扁平" (Flat) 结构**
|
|
||||||
* **`pitm` (主 ID):** `46`
|
|
||||||
* **`iref` (引用):** `dimg` (网格/派生图像) 列表是**空**的 (`'dimg': {46: []}`)。
|
|
||||||
* **`ipma` (属性):** 主 ID `46` **直接关联**到它自己的所有属性: `[1, 3, 5, 4]`。
|
|
||||||
* **`ipco` (属性库):** 索引 `[1, 3, 4, 5]` 对应 `colr` (色彩), `ispe` (**5712x4284** 的*完整*尺寸), `irot` (旋转), `pixi` (像素信息)。
|
|
||||||
* **结论:** 在 Apple 文件中,主 Item ID `46` *就是*那张 5712x4284 的图像。它是一个 "扁平" 文件。
|
|
||||||
|
|
||||||
**2. Samsung HEIC 是 "网格" (Grid) 结构**
|
|
||||||
* **`pitm` (主 ID):** `49`
|
|
||||||
* **`iref` (引用):** `dimg` 列表**不是空**的 (`'dimg': {1: [3, 4]}`)。这定义了一个网格,例如 "项目 1 是由图块 3 和 4 构成"。
|
|
||||||
* **`ipma` (属性):** 主 ID `49` **只关联**到一个属性:`[4]`。
|
|
||||||
* **`ipco` (属性库):** 索引 `[4]` 对应 `ispe` ( **4000x3000** 的*完整*尺寸)。
|
|
||||||
* **结论:** 在 Samsung 文件中,主 Item ID `49` **不是图像**,它只是一个*虚拟的*“描述符”,它只负责告诉解码器“最终图像是 4000x3000”。
|
|
||||||
* **致命缺陷:** `samsung.heic` 的 `[iloc]` 日志显示:`<ItemLocation ID=49 extents=1 total_size=8>`。
|
|
||||||
* 这意味着主 ID `49` 的**实际数据只有 8 字节**。真正的图像数据存储在*其他* Item ID 中(如 1, 3, 4...),然后通过 `iref` 盒的 `dimg` 网格蓝图拼凑起来。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 复盘:我们为什么一直失败
|
|
||||||
|
|
||||||
我们所有的修复(V8, V9, V10)都在做同一件事,而这件事是注定要失败的:
|
|
||||||
|
|
||||||
1. 我们拿了**三星的“网格”文件** (它依赖 `iref['dimg']` 来组合图像)。
|
|
||||||
2. 我们强行给它贴上了**苹果的 `ftyp` 标签** (例如 `...MiHBMiHE...`)。这个标签告诉解码器:“这是一个**扁平**文件,请勿查找 `iref['dimg']`”。
|
|
||||||
3. 我们正确地重建了所有偏移量,并注入了 `ContentIdentifier`。
|
|
||||||
|
|
||||||
**失败的精确时刻:**
|
|
||||||
|
|
||||||
1. Apple 的 "预览" App 打开我们的 `samsung_apple_compatible.HEIC`。
|
|
||||||
2. 它读取了 `ftyp` (苹果标签):“好的,这是一个扁平文件。”
|
|
||||||
3. 它读取了 `pitm`:“好的,主图像是 ID `49`。”
|
|
||||||
4. 它读取了 `ipma`:“好的,ID `49` 的尺寸是 4000x3000。”
|
|
||||||
5. 它去 `iloc` 查找 ID `49` 的**图像数据**。
|
|
||||||
6. `iloc` 返回:“这是它的数据:**8 个字节**。”
|
|
||||||
7. "预览" App 崩溃,因为它无法从 8 字节的数据中渲染出一个 4000x3000 的图像。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 结论:我们面临的僵局
|
|
||||||
|
|
||||||
我们无法通过*修改*(modify)来解决这个问题。**我们必须*转码*(transcode)。**
|
|
||||||
|
|
||||||
我们试图进行的“结构手术”是不可能的,因为这两种文件格式在如何定义“主图像”上存在根本性的、不兼容的差异。
|
|
||||||
|
|
||||||
**我们有两个选择,但都不能完全满足最初的需求:**
|
|
||||||
|
|
||||||
1. **选项 A:成功创建可查看的 HEIC(但丢失动态照片链接)**
|
|
||||||
* 我们可以使用 `heic_file.py` 中的 `reconstruct_primary_image()` 方法(它在内部使用 `pillow_heif`)。
|
|
||||||
* 这个方法很聪明,它*可以*读取三星的 `iref['dimg']` 网格并将其在内存中拼凑成一张完整的 4000x3000 图像。
|
|
||||||
* 然后我们可以将这张 `PIL.Image` 对象保存为一个**新的、扁平的** `output.heic` 文件。
|
|
||||||
* **结果:** 我们会得到一个完美的 HEIC 静态图像,但它将丢失我们辛苦注入的 `ContentIdentifier` (UUID),因为 `PIL.Image.save()` 只是一个像素编码器,它不会重建我们需要的复杂 `meta` 盒。
|
|
||||||
|
|
||||||
2. **选项 B:保持我们的代码(但它永远无法工作)**
|
|
||||||
* 我们当前的 `builder.py` 方案是*唯一*能够注入 `ContentIdentifier` 的方法,但它操作的*源文件*(三星网格)与我们的*目标*(苹果扁平)不兼容。
|
|
||||||
|
|
||||||
**简而言之:** 我们的 `builder.py` 擅长元数据(Metadata)操作,而 `pillow_heif` 擅长像素(Pixel)操作。要完成这个任务,我们**同时**需要两者,但现有的库不允许我们将 `ContentIdentifier` 注入到一个正在被转码(从网格转为扁平)的文件中。
|
|
||||||
|
|
||||||
我建议我们暂停对 `builder.py` 的修改,因为我们当前的偏移量计算(如 V10 日志所示)已经是**正确**的。失败的原因超出了我们的修复范围,它是一个文件*结构*的根本性不兼容。
|
|
||||||
|
|
||||||
实际上我的需求是:将三星的动态照片(motion photo)转换为两份文件,一份是视频一份是照片,将它们与iOS一样通过ContentIdentifier链接,使其变为可以被iOS设备读取并链接的Live Photo,我无所谓转换为静态照片的部分是否存在视频,但是我希望其可以注入ContentIdentifier,将三星的文件结构转换为iOS的文件结构
|
|
||||||
Reference in New Issue
Block a user