iPhone拍摄的照片中.AAE文件中的adjustmentData如何解码调整?

5

我理解.AAE文件应该描述了对某张图片所做的修改。然而,我发现大多数情况下(显然不总是这样),即使它们似乎携带相同的数据(这似乎表明没有对图片进行任何更改),仍会存在这样的文件。

是否有人知道如何解码这个adjustmentData值?

示例照片1:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>adjustmentBaseVersion</key>
    <integer>0</integer>
    <key>adjustmentData</key>
    <data>
    bZBNT8JAEIb/y5wrKaBg9mbwIBdJNNGD8TC003bNfjS7U5CQ/nenW0o4eNt95+t9nzNY
    YiyREdQZLEam8EK6bhjUfb5cZBftU5fcgFosVo8Z+KDJMbL2DtSqz6DywSJ/UIhJmmdw
    GN9bV/lh8b7Tpnzt7J4CKJivnx9yyADb9joD8o9FQxbf6KBHLc+gNcjDdmnQu3eQW1j+
    dJGtGIigvs7/3CaHe0MlKA4dyVZi1q6Og48THtNaSVBrh2YTfDv1/e6SmOrRYhACFZoo
    leMYfuRxmtqWa0EROeBAi9yTqw2BupNp7Nhfh5sLzRFd4V0acTxRzm/FC+YhuOZieEli
    XUpYXenELjmeiG9vK4W3MyFqaNY2Xgz03/0f
    </data>
    <key>adjustmentEditorBundleID</key>
    <string>com.apple.camera</string>
    <key>adjustmentFormatIdentifier</key>
    <string>com.apple.photo</string>
    <key>adjustmentFormatVersion</key>
    <string>1.6</string>
    <key>adjustmentTimestamp</key>
    <date>2020-03-21T17:37:31Z</date>
</dict>
</plist>

示例照片2:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>adjustmentBaseVersion</key>
    <integer>0</integer>
    <key>adjustmentData</key>
    <data>
    bZBNT8JAEIb/y5wrKaBg9mbwIBdJNNGD8TC003bNfjS7U5CQ/nenW0o4eNt95+t9nzNY
    YiyREdQZLEam8EK6bhjUfb5cZBftU5fcgFosVo8Z+KDJMbL2DtSqz6DywSJ/UIhJmmdw
    GN9bV/lh8b7Tpnzt7J4CKJivnx9yyADb9joD8o9FQxbf6KBHLc+gNcjDdmnQu3eQW1j+
    dJGtGIigvs7/3CaHe0MlKA4dyVZi1q6Og48THtNaSVBrh2YTfDv1/e6SmOrRYhACFZoo
    leMYfuRxmtqWa0EROeBAi9yTqw2BupNp7Nhfh5sLzRFd4V0acTxRzm/FC+YhuOZieEli
    XUpYXenELjmeiG9vK4W3MyFqaNY2Xgz03/0f
    </data>
    <key>adjustmentEditorBundleID</key>
    <string>com.apple.camera</string>
    <key>adjustmentFormatIdentifier</key>
    <string>com.apple.photo</string>
    <key>adjustmentFormatVersion</key>
    <string>1.6</string>
    <key>adjustmentTimestamp</key>
    <date>2020-03-25T05:45:21Z</date>
</dict>
</plist>

1
我查看了https://www.apple.com/DTDs/PropertyList-1.0.dtd,它说:“<!ELEMENT data (#PCDATA)> <!-- Contents interpreted as Base-64 encoded -->”,但是当我使用BASE64解码数据字段时,仍然显示乱码... - pjp
我做了同样的事情,结果是一个二进制plist文件,使用plutil -convert xml1转换为可读的XML。再次检查一下? - duozmo
3个回答

5
调整数据(adjustmentData)是一个JSON字符串,它经过zlib压缩,然后进行base64编码。我自己没有找到这个方法,ojchase 指出了base64编码的部分,然后我在 https://github.com/neilpa/photohack/issues/4#issuecomment-780872343 找到了其余内容。 https://github.com/RhetTbull/osxphotos/issues/384 说明在某些情况下格式是不同的,但目前我没有任何可供检查的示例。
我使用Python解码adjustmentData,因为我发现它有一些相关的库: 代码在Windows 10上使用Python 3.9.12进行测试。使用来自iPhone SE(第2代),iOS版本16.1.1的AAE文件进行测试,但脚本包含了pjp的adjustmentData以回答该问题。这两个示例AAE文件都包含相同的adjustmentData。
import base64
import zlib
import json

# adjustmentData merged into one continuous string without whitespaces, stored as bytestring
adjustmentData = b"bZBNT8JAEIb/y5wrKaBg9mbwIBdJNNGD8TC003bNfjS7U5CQ/nenW0o4eNt95+t9nzNYYiyREdQZLEam8EK6bhjUfb5cZBftU5fcgFosVo8Z+KDJMbL2DtSqz6DywSJ/UIhJmmdwGN9bV/lh8b7Tpnzt7J4CKJivnx9yyADb9joD8o9FQxbf6KBHLc+gNcjDdmnQu3eQW1j+dJGtGIigvs7/3CaHe0MlKA4dyVZi1q6Og48THtNaSVBrh2YTfDv1/e6SmOrRYhACFZooleMYfuRxmtqWa0EROeBAi9yTqw2BupNp7Nhfh5sLzRFd4V0acTxRzm/FC+YhuOZieEliXUpYXenELjmeiG9vK4W3MyFqaNY2Xgz03/0f"

# Decode base64 encoded bytes. This will result some not-readable binary data
adjustmentData_decoded = base64.b64decode(adjustmentData)

# Decompress
adjustmentData_decompressed = zlib.decompress(adjustmentData_decoded, -zlib.MAX_WBITS)
adjustmentData_json = json.loads(adjustmentData_decompressed)
    
print(json.dumps(adjustmentData_json, indent=2))

输出结果如下:
{
  "metadata": {
    "masterHeight": 4032,
    "masterWidth": 2268,
    "orientation": 6
  },
  "formatVersion": 1,
  "versionInfo": {
    "buildNumber": "17D50",
    "appVersion": "",
    "schemaRevision": 0,
    "platform": "iOS"
  },
  "adjustments": [
    {
      "formatVersion": 1,
      "enabled": true,
      "settings": {
        "yaw": 0,
        "originalCrop": true,
        "xOrigin": 0,
        "smart": false,
        "width": 4032,
        "yOrigin": 378,
        "straightenAngle": 0,
        "auto": false,
        "height": 2268,
        "constraintHeight": 0,
        "constraintWidth": 0,
        "pitch": 0
      },
      "identifier": "Crop",
      "formatIdentifier": "com.apple.photo"
    }
  ]
}

其他经验:

  • 如果我们不编辑照片,我们仍然可以拥有AAE文件。我的经验是,如果我们使用16:9的宽高比,则会发生这种情况。然后iPhone会存储原始的4:3照片,并通过AAE文件应用宽高比。这使得以后可以在编辑器中修改照片的比例和方向。
  • 如果我通过USB将iPhone连接到电脑上,那么我可以通过Windows文件浏览器浏览照片,对于每张照片,我可以看到:
    • 存储了两个几乎相同的AAE文件。唯一的区别是其中一个包含adjustmentRenderTypes xml PropertyList键
    • 两个HEIC文件:IMG_<number>.HEICIMG_E<number>.HEIC。第一个是原始的4:3图像,第二个似乎应用了AAE编辑。

文件浏览器截图


2
很遗憾,这还不是一个完整的答案。它可能会有所帮助,但我还有一些不理解的地方。
我找到的最有用的答案来自http://rae.tnir.org/archives/2016/02/data-inside-apples-aae-files。他将data属性的内容通过base64解码,然后得到一个二进制plist,将其转换为与照片慢动作设置相关的可读XML。
让我们更详细地了解一下。
从他的adjustmentData信息开始:
    <key>adjustmentData</key>
    <data>
    YnBsaXN0MDDRAQJac2xvd01vdGlvbtIDBAUXV3JlZ2lvbnNUcmF0ZaEG0QcIWXRpbWVS
    YW5nZdIJCgsUVXN0YXJ0WGR1cmF0aW9u1AwNDg8QERITVWZsYWdzVXZhbHVlWXRpbWVz
    Y2FsZVVlcG9jaBABEQEMEQJYEADUDA0ODxUWEhMQAxEC4SI+AAAACAsWGyMoKi03PEJL
    VFpganBydXh6g4WIAAAAAAAAAQEAAAAAAAAAGAAAAAAAAAAAAAAAAAAAAI0=
    </data>

我们将对data值进行Base64解码。空格和换行似乎并不重要。使用https://www.opinionatedgeek.com/codecs/base64decoder,因为我们希望将结果保存为二进制文件,而只显示文本结果的转换器无法正确渲染它。复制data字段(YnBs.....AAI0=),解码它,并下载结果文件。请注意,它以bplist开头,表明它是用于苹果生态系统中的二进制plist。
现在我们需要解码二进制plist。他没有解释如何做到这一点,但其他网站声称您可以在TextMate中打开它并知道如何显示它。确实。上面的评论中,另一个苹果建议是运行plutil -convert xml1 TheDownloadedFile,它会将文件从二进制版本修改为XML版本。(它们似乎在我借来测试的Mac上都有效。)但我在Windows上,两个建议都没有帮助。然而,我能够在Notepad++中找到Notepad++ bplist插件。对于我在Notepad++中显示的最终结果是:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>slowMotion</key>
    <dict>
        <key>regions</key>
        <array>
            <dict>
                <key>timeRange</key>
                <dict>
                    <key>start</key>
                    <dict>
                        <key>flags</key>
                        <integer>1</integer>
                        <key>value</key>
                        <integer>268</integer>
                        <key>timescale</key>
                        <integer>600</integer>
                        <key>epoch</key>
                        <integer>0</integer>
                    </dict>
                    <key>duration</key>
                    <dict>
                        <key>flags</key>
                        <integer>3</integer>
                        <key>value</key>
                        <integer>737</integer>
                        <key>timescale</key>
                        <integer>600</integer>
                        <key>epoch</key>
                        <integer>0</integer>
                    </dict>
                </dict>
            </dict>
        </array>
        <key>rate</key>
        <real>0.125000</real>
    </dict>
</dict>
</plist>


请参阅从plist文件解码数据。 还有,此处链接的评论非常有帮助。 他的plist不是AAE图像,但相同的过程适用。 对于任何plist,我会怀疑它是否起作用。

除了你的和我的。 我不知道为什么。

在这个最初的问题中,adjustmentData data值不能解码为以bplist开头的内容。 相同的解码器(https://www.opinionatedgeek.com/codecs/base64decoder)将其解码为:

mO@@†˜+) 箠I4у൓0´v̾4»þ§J8xڽ誽ŸXb,‘ҙ,F¦Bºӽ¾d쓗܀Z,V籲ϠPˆšpޛWΐ¦(˜Ÿrƀܶ:ࠨG-Ϡ5ɃviлwXþ‘ˆ¾ÿ&‡C%(Ȗb֮ŽҚIPk‡|;˜Тš•~㱚ږkA9@‹“
“헟‡ˑ]ۚq<QͯË䡸塸Ib]JX]ꂮ9žoo+…3!jhԶ^ໟ

我使用任何其他解码器或更改空格都没有更好的成功率。 我现在面临着让我自己陷入困境的AAE相同的问题。 我注意到你和我都有频繁出现斜杠字符的数据,而我链接的两个成功案例却没有。 对我来说,它们“感觉”像是不同的编码方式,但我不是编码专家。

我也对原始AAE文件中的adjustmentFormatVersion有些怀疑。 工作示例是1.1版本。 而我们的是1.4和1.6。 我想知道内容以前是否为二进制plist,但现在不再是。


2

adjustmentData 很可能是在 苹果的 PhotoKit 文档 中提到的应用程序特定的附加数据:

该对象提供了一个应用程序定义的“配方”,您可以使用它来重建编辑。

当资产被编辑时,照片会存储由编辑资产的应用程序(或扩展)提供的 PHAdjustmentData 对象。此对象提供了重建使用资产之前版本的内容进行编辑所需的任何信息。当用户尝试使用您的扩展编辑资产时,Photos 调用此块以了解您的扩展是否可以处理资产的过去调整。

由于这是应用程序特定的数据,并且现在高度编码化(不再仅仅是二进制 plist),我猜它是某种存档的 NSData 对象(示例自定义实现)。但是,如果不知道字节映射到什么(Photos.app 编码器做什么,是否需要任何枚举),我们可能无法进一步解码它们。(对于参考,我的系统上有版本为 1.8 的 AAE 文件。)

从 iOS 8(2014)开始,这些可能是 易于解码的。如果我们曾经找到或反向工程一些参考代码(来自 Photos.app 或其他),将信息编码到 .swift shell 脚本中应该很容易。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接