【问题标题】:Converting BMP into grayscale using Python使用 Python 将 BMP 转换为灰度
【发布时间】:2017-04-15 09:46:20
【问题描述】:

我正在尝试使用 python 将 BMP 图像转换为灰度图像。这是正确的问题。

编写一个程序来编辑一个图像文件,把它变成灰度。 将每个像素替换为具有相同灰度级的像素 蓝色、绿色和红色分量。灰度级由下式计算 添加 30% 的红色电平,59% 的绿色电平,以及 蓝色水平的 11%。 (色觉视锥细胞 人眼对红光、绿光和蓝光的敏感度不同。)

我已经进行了一些编码,但它实际上并没有变成灰度,而是或多或少地变成了奇怪颜色的混合物。有人可以更正我的代码并看看我做错了什么吗?这是我的代码

from io import SEEK_CUR
def main():
    filename = input("Please enter the file name: ")

    # Open as a binary file for reading and writing
    imgFile = open(filename, "rb+")

    # Extract the image information.
    fileSize = readInt(imgFile, 2)
    start = readInt(imgFile, 10)
    width = readInt(imgFile, 18)
    height = readInt(imgFile, 22)

    # Scan lines must occupy multiples of four bytes.
    scanlineSize = width * 3
    if scanlineSize % 4 == 0:
        padding = 0
    else :
        padding = 4 - scanlineSize % 4

    # Make sure this is a valid image.
    if fileSize != (start + (scanlineSize + padding) * height):
        exit("Not a 24-bit true color image file.")

    # Move to the first pixel in the image.
    imgFile.seek(start)# Process the individual pixels.
    for row in range(height): #For each scan line
        for col in range(width): #For each pixel in the line
            processPixel(imgFile)

        # Skip the padding at the end.
        imgFile.seek(padding, SEEK_CUR)

    imgFile.close()## Processes an individual pixel.#@param imgFile the binary file containing the BMP image#

def processPixel(imgFile): #Read the pixel as individual bytes.
    theBytes = imgFile.read(3)
    blue = theBytes[0]
    green = theBytes[1]
    red = theBytes[2]

    # Process the pixel.
    newBlue = 255 - blue
    newGreen = 255 - green
    newRed = 255 - red

    # Write the pixel.
    imgFile.seek(-3, SEEK_CUR)# Go back 3 bytes to the start of the pixel.
    imgFile.write(bytes([newBlue, newGreen, newRed]))## Gets an integer from a binary file.#@param imgFile the file#@ param offset the offset at which to read the integer#@


def readInt(imgFile, offset): #Move the file pointer to the given byte within the file.
    imgFile.seek(offset)

    # Read the 4 individual bytes and build an integer.
    theBytes = imgFile.read(4)
    result = 0
    base = 1
    for i in range(4):
        result = result + theBytes[i] * base
        base = base * 256

    return result# Start the program.
main()

【问题讨论】:

    标签: python python-3.x


    【解决方案1】:

    看这里

    imgFile.write(bytes([newBlue, newGreen, newRed]))
    

    让我们看看bytes做了什么

    In [1]: ?bytes
    Type:        type
    String form: <type 'str'>
    Namespace:   Python builtin
    Docstring:
    str(object='') -> string
    
    Return a nice string representation of the object.
    If the argument is a string, the return value is the same object.
    
    In [2]: bytes(10)
    Out[2]: '10'
    
    In [3]: bytes([10,9])
    Out[3]: '[10, 9]'
    

    如您所见,它似乎并没有按照您的想法行事。

    您正在寻找 bytearray

    In [4]: ?bytearray
    Type:        type
    String form: <type 'bytearray'>
    Namespace:   Python builtin
    Docstring:
    bytearray(iterable_of_ints) -> bytearray.
    bytearray(string, encoding[, errors]) -> bytearray.
    bytearray(bytes_or_bytearray) -> mutable copy of bytes_or_bytearray.
    bytearray(memory_view) -> bytearray.
    
    Construct an mutable bytearray object from:
      - an iterable yielding integers in range(256)
      - a text string encoded using the specified encoding
      - a bytes or a bytearray object
      - any object implementing the buffer API.
    
    bytearray(int) -> bytearray.
    
    Construct a zero-initialized bytearray of the given length.
    
    In [5]: bytearray([1,2,3])
    Out[5]: bytearray(b'\x01\x02\x03')
    

    【讨论】:

    • 如何在代码中实现它,然后添加 30% 的红色级别、59% 的绿色级别和 11% 的蓝色级别。?
    • 所以,添加 30% 等于将其乘以 1.3。在 python 中,如果你将一个浮点数和一个整数相乘,你最终会得到一个浮点数,所以你需要使用int 函数再次使其成为bytearray-able,例如newRed = int(red*1.3)。您还需要确保不超过 256,因为 bytearray 会抱怨。
    • 您能否将其添加到我的代码中。我仍然不确定如何将字节更改为 bytearray
    • 所以这一行:imgFile.write(bytes([newBlue, newGreen, newRed])) 应该使用bytearray 而不是bytes
    • 谢谢。 30% 不应该是 0.3 吗?
    【解决方案2】:
    In this area of your code:
    
    def processPixel(imgFile): #Read the pixel as individual bytes.
        theBytes = imgFile.read(3)
        blue = theBytes[0]
        green = theBytes[1]
        red = theBytes[2]
    #ADD THIS LINE OF CODE
        gray = int((0.2126*red)+(0.7152*green)+(0.0722*blue))
        # Process the pixel.
    #CHANGE IT TO THE FOLLOWING COLORS BY SUBTRACTING THE "gray" from 255
        newBlue = 255 - gray
        newGreen = 255 - gray
        newRed = 255 - gray
    

    【讨论】:

      猜你喜欢
      • 2013-05-05
      • 2020-03-21
      • 1970-01-01
      • 2014-04-25
      • 2017-01-17
      • 2021-06-06
      • 2016-06-18
      • 1970-01-01
      • 2019-12-03
      相关资源
      最近更新 更多