Gimp:如何使用 python 脚本将没有颜色 space 信息的图像导出为 BMP?

Gimp: How to export an image to BMP without the color space information using a python script?

我正在为 Gimp 编写 python 脚本以将图像的所有层导出到 BMP。

要导出给定图层,我使用程序 file_bmp_save:

pdb.file_bmp_save(image, layer, filename, raw_filename)

但是这个函数在BMP文件头中保存了颜色space信息。

当我手动导出BMP时(File > Export),有一个选项

do not write color space information

See screen capture

我想在我的 python 脚本中重现这个选项。

所以 - 我去检查了一下,确实 - 这个选项根本无法以编程方式使用。 案例是在 GIMP BMP 导出过滤器上命名为 "color space information" 的块实际上是版本 3 BMP 文件和版本 4 bmp 文件之间的二进制差异,早在 Windows 就引入了95.

因此,我请求您重新考虑您在哪里使用需要文件版本高达 Pre-windows 95 文件的 BMP 文件。

就是说,在某些时候,具有 GIMP 黑客能力的人觉得有必要,并将这些 v3 文件的选项添加到导出 GUI - 但同一个人并没有为 PDB 保存添加第二个 PDB 调用: file_bmp_save 调用本身无法更改为具有额外的 "dont_write_color_information" 参数 - GIMP PDB 调用在主要 GIMP 版本之间保持向后兼容(就像永远一样)。并且大约在 2004 年、2005 年添加第二个过程以支持保存 1995 年废弃的文件版本,将适得其反。

幸运的是,在 V4 末尾写入的只是 68 个字节 header - 不同的偏移量仅记录在文件中的 3 个点中。因此,很容易编写一个 Python 解决方案来将这些文件转换为您需要的格式。

如果转换更复杂,路径将是:使用 GIMP 项目提交错误,以便可以对 GUI 退出选项进行编程调用,(最好为此编写补丁并附加它错误,因为 GIMP 是一个仅限志愿者的项目)并等待具有更改的新版本 GIMP。同时,使用可以进行所需图像转换的外部程序(或您自己的 GIMP 补丁版本)的解决方法。

尽管如此,下面的Python函数将在 GIMP 导出后转换 BMP 版本:

import struct

V4_HEADER_SIZE = 108
COLOR_INFO_SIZE = 68
HEADER_OFF = 14
DATA_OFF_FIELD = 10
SIZE_OFF  =  2
def strip_color_info(old_bmp_name, new_bmp_name=None):
    if new_bmp_name is None:
        new_bmp_name = old_bmp_name
    data = bytearray(open(old_bmp_name, "rb").read())
    header_size = struct.unpack("I", data[HEADER_OFF: HEADER_OFF + 4])[0]
    if header_size == 108:
        # Remove 68  - the size for the extra data-chunk from both headers
        data[HEADER_OFF: HEADER_OFF + 4] = struct.pack("I", V4_HEADER_SIZE - COLOR_INFO_SIZE)
        data[DATA_OFF_FIELD: DATA_OFF_FIELD + 4] = struct.pack("I",
            struct.unpack("I",data[DATA_OFF_FIELD: DATA_OFF_FIELD + 4])[0] - COLOR_INFO_SIZE)
        # Offset image data:
        data[HEADER_OFF + header_size - COLOR_INFO_SIZE:] =  data[HEADER_OFF + header_size:]
        data[SIZE_OFF: SIZE_OFF + 4] = struct.pack("I", len(data))
    with open(new_bmp_name, "wb") as output_file:
        output_file.write(data)

(免责声明:我刚刚用 RGB 24bpp 文件对此进行了测试 - 尽管它也适用于其他格式)