在简单的 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
显然每个像素都是带状宽度。
现在打印机的输出是正确的。
这是代码。
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
显然每个像素都是带状宽度。
现在打印机的输出是正确的。