在 python 3 中处理 .bmp 文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20276458/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 20:04:46  来源:igfitidea点击:

working with .bmp files in python 3

pythonimagepython-3.xbmp

提问by amin

I have a bmp file. It is just a red square. I have to write a program with functions to make it have white stripes. Things I would need to do:

我有一个bmp文件。它只是一个红色方块。我必须编写一个带有函数的程序以使其具有白色条纹。我需要做的事情:

  • load the bmp file.
  • read and assess the bmp file.
  • code certain areas coordinates of the file to be colored white.
  • close the file
  • display the end product file as output
  • 加载 bmp 文件。
  • 阅读并评估 bmp 文件。
  • 将文件的某些区域坐标编码为白色。
  • 关闭文件
  • 将最终产品文件显示为输出

i am a novice, and am having trouble reading or displaying the original bmp file, let alone edit the content inside. it is not similar to opening a txt file and "readline()". also, when i copy paste the bmp file in the pydev projects src folder in eclipse, it does not show up on eclipse, so i don't know if how the computer would recognize that the file is there. i want to read up on it before posting here, but i don't seem to get much results googling, since i am not sure exactly what i should search for.

我是新手,在阅读或显示原始bmp文件时遇到问题,更不用说编辑里面的内容了。它与打开 txt 文件和“readline()”不同。另外,当我将 bmp 文件复制粘贴到 Eclipse 的 pydev 项目 src 文件夹中时,它不会显示在 Eclipse 上,所以我不知道计算机是否会识别该文件在那里。我想在这里发帖之前仔细阅读它,但我似乎没有得到太多的谷歌搜索结果,因为我不确定我应该搜索什么。

采纳答案by abarnert

The easy way to do this is with a third-party image-processing library like PIL/Pillow. The code is simple enough that you could figure it out in a few minutes from the examples on the Imagemodule docs…

最简单的方法是使用第三方图像处理库,如PIL/Pillow。代码非常简单,您可以在几分钟内从Image模块文档中的示例中弄清楚……

But if you're not allowed to do that, let's look at how to do this manually.

但是,如果您不允许这样做,让我们看看如何手动执行此操作。

First, BMP isn't a text file format, it's a binaryformat. That means you have to read it in binary mode. And you can't read it "line by line", because it doesn't have lines of text to read. Since a bytesobject isn't mutable, you will probably want to copy it into a bytearrayto work with. So:

首先,BMP 不是文本文件格式,而是二进制格式。这意味着您必须以二进制模式读取它。而且您无法“逐行”阅读它,因为它没有要阅读的文本行。由于bytes对象不是可变的,您可能希望将其复制到 abytearray中使用。所以:

with open('spam.bmp', 'rb') as f:
    data = bytearray(f.read())

Next, you need to parse the BMP file format. I assume the main point of the exercise is figuring out how to do that yourself, so I'll give you a link to Wikipedia's article, which describes it better than the Microsoft docs, and you can go from there.

接下来,您需要解析 BMP 文件格式。我认为练习的重点是弄清楚如何自己做,所以我会给你一个链接到Wikipedia 的文章,它比 Microsoft 文档更好地描述它,你可以从那里开始。

The structmodule in the standard library will be very helpful for interpreting the headers; it's much easier to read a 32-bit little-endian number with struct.unpack_from('<L', data, offset)than with by reading data[offset], data[offset+1], etc. and re-combining them into a 32-bit number.

struct标准库中的模块对解释头文件非常有帮助;它更容易阅读与32位小尾数号码struct.unpack_from('<L', data, offset)通过阅读比data[offset]data[offset+1]等等,并将它们重新组合成一个32位的数字。

I'm guessing you can ignore all the options for BMP compression—otherwise, this would be way too hard an assignment. In fact, you can probably just assume that all of the headers will specify the most common variant and only code for that. But you might want to ask your teacher for feedback on that.

我猜你可以忽略 BMP 压缩的所有选项——否则,这将是一项太难的任务。事实上,您可能只是假设所有标头都将指定最常见的变体,并且仅指定了该变体的代码。但是你可能想向你的老师征求反馈意见。

Now, once you've found the "pixel array" portion of the BMP, and you've figured out how to interpret it from the DIB header, you can just set pixels to white at whichever positions you want by setting the values at the appropriate indexes of the bytearray. For example, it may turn out to be as simple as:

现在,一旦您找到了 BMP 的“像素阵列”部分,并且您已经弄清楚如何从 DIB 标头中解释它,您可以通过设置值在您想要的任何位置将像素设置为白色字节数组的适当索引。例如,结果可能很简单:

pos = pixel_array_offset + row_size * y + pixel_size * x
data[pos:pos+3] = 255, 255, 255

Finally, once you've changed your red pixels to white, you can save it with:

最后,一旦您将红色像素更改为白色,您可以将其保存为:

with open('eggs.bmp', 'wb') as f:
    f.write(data)