在简单的 PIL 位图中,从一个像素到下一个像素的字节顺序很奇怪。什么可能是错误的?

Weird ordering of bytes from one pixel to the next in simple PIL bitmap. What is likely wrong?

这是代码。

import os
import io
import PIL
#import pyximport;  pyximport.install()
#from pixel_tools import PixelsBMP
from PIL import Image, ImageGrab

# TODO convert to Cython

class PixelsBMP:
    def __init__(self, img):
        if isinstance(img, str):
            img = Image.open(img)

        with io.BytesIO() as bytes_io:
            img.save(bytes_io, 'BMP')
            data = bytes_io.getvalue() 
            offset = int.from_bytes(data[10:14], byteorder='little', signed=False)
            data = data[offset:]        # pixels start here

        self.data = data
        self.width = img.width
        self.height = img.height
        self.bands = 3 if img.mode == 'RGB' else 4

    def debugPrintPixels(self):
        import sys
        d = self.data
        print('width:', self.width)
        print('height:', self.height)
        print('bands (alpha=>4):', self.bands)
        for y in range(0, self.height):
            for x in range(0, self.width):
                offs = self.width * self.bands * y + x
                sys.stdout.write('(' + str(d[offs]) + ',' + str(d[offs + 1]) + ',' + str(d[offs + 2]) + ((',' + str(d[offs + 3])) if self.bands == 4 else '') + ')')
            print()

if __name__ == '__main__':
    subpx = PixelsBMP('images/PixelsBMP_test_subImage.png')
    subpx.debugPrintPixels()

    ##pixels = PixelsBMP('images/PixelsBMP_test_superImage.png')

    ##point = pixels.exactSubpixelSearch(subpx)

    #print(point)
    print('test done')

它打印的是:

width: 7
height: 3
bands (alpha=>4): 4
(100,50,25,255)(50,25,255,100)(25,255,100,50)(255,100,50,25)(100,50,25,255)(50,25,255,100)(25,255,100,50)
(100,50,25,255)(50,25,255,100)(25,255,100,50)(255,100,50,25)(100,50,25,255)(50,25,255,100)(25,255,100,50)
(100,50,25,255)(50,25,255,100)(25,255,100,50)(255,100,50,25)(100,50,25,255)(50,25,255,100)(25,255,100,50)
None
test done

对于这张 7x3 海军蓝位图。像素是:(25, 50, 100) 实心 RGB。


(很小,就在这一行之后):


因此,BGR 顺序在这里并不令人震惊或重要,但顺序从第一个像素到第二个像素的变化这一事实: (100,50,25,255)(50,25,255,100).

今晚我很懒。我做错了什么?

发现问题:

offs = self.width * self.bands * y + x

在 debugPrint 例程中应该是:

offs = self.width * self.bands * y + x * self.bands

显然每个像素都是带状宽度。

现在打印机的输出是正确的。