3

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

要导出给定层,我使用以下过程file_bmp_save

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

但是这个函数将色彩空间信息保存在 BMP 头中。

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

不写色彩空间信息

查看屏幕截图

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

4

1 回答 1

4

所以 - 我去检查它,确实 - 这个选项根本无法以编程方式使用。案例是在 GIMP BMP 导出过滤器上被命名为“颜色空间信息”的块实际上是版本 3 BMP 文件和版本 4 bmp 文件之间的二进制差异,该文件早在 Windows 95 中就引入了。

所以,我请求您重新考虑您在哪里使用 BMP 文件,这些文件需要像 Pre-windows 95 文件一样旧的文件版本。

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

幸运的是,在 V4 标头末尾写入的只是 68 个字节的问题 - 不同的偏移量记录在文件中的 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 文件对此进行了测试——尽管它也适用于其他格式)

于 2015-05-29T13:37:04.477 回答