我正在为 Gimp 编写一个 python 脚本,以将图像的所有层导出到 BMP。
要导出给定层,我使用以下过程file_bmp_save
:
pdb.file_bmp_save(image, layer, filename, raw_filename)
但是这个函数将色彩空间信息保存在 BMP 头中。
当我手动导出 BMP ( File > Export
) 时,有一个选项
不写色彩空间信息
我想在我的 python 脚本中重现这个选项。
所以 - 我去检查它,确实 - 这个选项根本无法以编程方式使用。案例是在 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 文件对此进行了测试——尽管它也适用于其他格式)