【问题标题】:How can I detect JPEG files by their EXIF / JFIF signature?如何通过 EXIF / JFIF 签名检测 JPEG 文件?
【发布时间】:2018-08-20 13:23:14
【问题描述】:

几天前,我 asked a question in a different field 和最后一位朋友 (@emcconville) 帮我编写了一个脚本,用于“在单个文件中恢复每个 JPEG 文件”。 现在我意识到这个程序只适用于标准“JFIF”的图像,不能检索“EXIF”标准的图像(数码相机拍摄的图像)。

如何更改程序,使其也可以知道图像中的 Exif 标准? 我不熟悉 Python,也不知道它的威力。

谢谢

import struct

with open('src.bin', 'rb') as f:
    # Calculate file size.
    f.seek(0, 2)
    total_bytes = f.tell()
    # Rewind to beging.
    f.seek(0)
    file_cursor = f.tell()
    image_cursor = 0

    while file_cursor < total_bytes:
        # Can for start of JPEG.
        if f.read(1) == b"\xFF":
            if f.read(3) == b"\xD8\xFF\xE0":
                print("JPEG FOUND!")
                # Backup and find the size of the image
                f.seek(-8, 1)
                payload_size = struct.unpack('<I', f.read(4))[0]
                # Write image to disk
                d_filename = 'image{0}.jpeg'.format(image_cursor)
                with open(d_filename, 'wb') as d:
                    d.write(f.read(payload_size))
                image_cursor += 1
        file_cursor = f.tell()

【问题讨论】:

    标签: python exif jfif


    【解决方案1】:

    EXIF 文件的标记为 0xffe1,JFIF 文件的标记为 0xffe0。所以所有依赖 0xffe0 来检测 JPEG 文件的代码都会 错过所有 EXIF 文件。 (from here)

    所以改变

    if f.read(3) == b"\xD8\xFF\xE0":
    

    if f.read(3) == b"\xD8\xFF\xE1":
    

    如果您想同时检查这两种情况,请不要再像这样使用.read()。取而代之的是

    x = f.read(3)
    if x in (b"\xD8\xFF\xE0", b"\xD8\xFF\xE1"):
    

    【讨论】:

    • 感谢它的魅力。但是如果我在“if f.read(3)”中使用“或”让程序从文件中恢复 JFIF 和 EXIF 图像,它将失败!为什么它不能这样做?
    • 因为f.read()实际上是从文件中的标记位置读取数据。每次读取后,标记会移动,在您的情况下移动三个字节。如果您正在使用一个.read(3) 操作,则读取标记会移动,并且您不再处于正确的位置。而是使用我上面添加的东西。
    • 我犯了多么可笑的错误!你说的对 。非常感谢
    猜你喜欢
    • 1970-01-01
    • 2010-11-28
    • 1970-01-01
    • 1970-01-01
    • 2014-06-25
    • 2022-09-25
    • 1970-01-01
    • 1970-01-01
    • 2015-02-25
    相关资源
    最近更新 更多