【问题标题】:How to add a header to a bmp image without header?如何在没有标题的 bmp 图像中添加标题?
【发布时间】:2019-05-28 18:47:33
【问题描述】:

我正在使用一个产品,我可以向它发送 BMP 文件,但它只接受没有标题的 BMP,所以我删除了标题。 但是该产品可以将其 BMP 文件发送给我,我想在网页上显示它们,因此我需要重新创建标题以使其正常工作。

解决方案可能是将标头存储在我的文件系统或数据库中,但我想知道是否有重新创建标头的解决方案,例如pillow

目前我只是像这样打开我的 BMP(24 位,无标题)文件:

logo_file = open(django_settings.UPLOAD_DIR+'logos/1568/logo1-no-header.bmp', 'rb').read()

也许可以将二进制数据转换为像素并使用pillow 创建新图像,插入像素并保存到 BMP?

【问题讨论】:

  • 当你说没有头文件时,你的意思是没有文件头,还是没有DIB头?因为,您剩下的只是原始像素,您可以读取它们并将其放入数组中。但是如果无法以某种方式访问​​该信息,您将无法了解图像的宽度/高度。并且假设每个像素的颜色平面/比特数是固定的。
  • 我根据规范 fastgraph.com/help/bmp_header_format.html 删除了前 54 个字节。但我知道大小(164*68),所以应该可以重新创建表头。
  • 我不知道如何从 :logo_file = open(django_settings.UPLOAD_DIR+'logos/1568/logo1-no-header.bmp', 'rb').read 中的数据创建数组()。我得到一个打开的字节。
  • 您到底想达到什么目的?有了原始数据,您可以使用image = Image.frombytes('RGB', (164, 68), logo_file) 创建一个 Image 对象。之后,您可以使用image.save() 将其保存到文件中,或者使用np.array(image) 提取数组中的像素。

标签: python bitmap python-imaging-library pillow


【解决方案1】:

你看过construct吗?支持BMP。

我建议看一下这个较早的问题,虽然不完全相同,但有一些应该有所帮助的例子。 how to create bmp file

【讨论】:

  • 我不确定这如何回答实际问题。他可以读取原始数据,因此不需要解析器,但是如果标题中没有一些关键信息,他将无法重建实际图像以供显示。而且他绝对没有要保存为二进制数据的像素数组。
  • ok,哈哈,所以即使使用 imagemagick,也无法重新显示无头文件?
【解决方案2】:

为了使用 Pillow 将每像素 24 位 BMP 的原始像素数据按摩成完整的图像文件,需要做两件事:

  • 将图像上下翻转,因为 BMP 会自下而上保存像素行,
  • 并重新排序像素组件,因为 BMP 以蓝色、绿色、红色顺序存储像素,但 Pillow 仅支持 RGB 顺序。

假设您在一个名为 test.dat 的文件中有 33456 字节的原始像素数据:

#!/usr/bin/env python
from __future__ import absolute_import, division, print_function
from PIL import Image


def main():
    with open('test.dat', 'rb') as data_file:
        raw_data = data_file.read()
    red, green, blue = Image.frombytes('RGB', (164, 68), raw_data).split()
    image = Image.merge('RGB', (blue, green, red))
    image = image.transpose(Image.FLIP_TOP_BOTTOM)
    image.save('result.bmp')


if __name__ == '__main__':
    main()

这是一个创建示例test.dat的小程序:

#!/usr/bin/env python3
import base64
import gzip

DATA = b'''\
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'''


def main():
    with open('test.dat', 'wb') as file:
        file.write(gzip.decompress(base64.decodebytes(DATA)))


if __name__ == '__main__':
    main()

【讨论】:

  • 谢谢,我要试试。最后我们决定产品不会发回没有标题的 bmp 图像。但我希望这个问题能为某人服务。
  • 不幸的是,我没有运气让这种方法发挥作用。
  • @DavidB 它对我有用。我已将示例数据添加到答案中。您在使用这种方法时遇到了什么问题?
  • @BlackJack 我不确定是什么导致这种方法出现问题,但我生成的位图都已损坏。我正在尝试从用户传入的任何文件(不仅仅是图像)生成图像,所以也许这就是问题所在。我通过使用 Pillow 库解决了这个问题,但我仍然想学习如何使用这种方法生成图像。
  • @DavidB 这个问题是关于从每像素 24 位 BMP 文件的二进制数据中重建图像,没有标题但以像素为单位的已知大小。该代码不能按原样用于将任何文件转换为 BMP 图像。 任何 文件都会变得棘手,因为像素数据大小必须能被 4 整除,并且您需要为标题提供合理的宽度和高度信息。请记住,需要以一种防止像素行填充的方式选择宽度,因此实际上所有数据都用于像素,而没有任何数据作为填充。有趣的挑战,但却是一个完全不同的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多