mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-24 17:06:16 +03:00
bug fix: Qt wants data aligned to 32 bits
Images in Qt show up incorrectly if each line is not aligned to 32 bits. It is pretty common for an image's lines to be 32-bit alinged by chance. Obviously any 32-bit image will not have any problem. For the bug to manifest itself you'd need... * a 1-bit image whose width is not a multiple of 32 * an 8-bit image who width is not a multiple of 4 Testing more images now and added a 7x13 png test image
This commit is contained in:
parent
58af64e245
commit
86e775daa3
|
@ -80,6 +80,33 @@ def fromqpixmap(im):
|
|||
# bytes_io.seek(0)
|
||||
# return PIL.Image.open(bytes_io)
|
||||
|
||||
def align8to32(bytes, width, mode):
|
||||
"""
|
||||
converts each scanline of data from 8 bit to 32 bit aligned
|
||||
"""
|
||||
|
||||
bits_per_pixel = {
|
||||
'1': 1,
|
||||
'L': 8,
|
||||
'P': 8,
|
||||
}[mode]
|
||||
|
||||
# calculate bytes per line and the extra padding if needed
|
||||
bits_per_line = bits_per_pixel * width
|
||||
full_bytes_per_line, remaining_bits_per_line = divmod(bits_per_line, 8)
|
||||
bytes_per_line = full_bytes_per_line + (1 if remaining_bits_per_line else 0)
|
||||
|
||||
extra_padding = -bytes_per_line % 4
|
||||
|
||||
# already 32 bit aligned by luck
|
||||
if not extra_padding:
|
||||
return bytes
|
||||
|
||||
new_data = []
|
||||
for i in range(len(bytes) / bytes_per_line):
|
||||
new_data.append(bytes[i*bytes_per_line:(i+1)*bytes_per_line] + '\x00' * extra_padding)
|
||||
|
||||
return ''.join(new_data)
|
||||
|
||||
def _toqclass_helper(im):
|
||||
data = None
|
||||
|
@ -123,7 +150,7 @@ def _toqclass_helper(im):
|
|||
raise ValueError("unsupported image mode %r" % im.mode)
|
||||
|
||||
# must keep a reference, or Qt will crash!
|
||||
__data = data or im.tobytes()
|
||||
__data = data or align8to32(im.tobytes(), im.size[0], im.mode)
|
||||
return {
|
||||
'data': __data, 'im': im, 'format': format, 'colortable': colortable
|
||||
}
|
||||
|
|
BIN
Tests/images/7x13.png
Normal file
BIN
Tests/images/7x13.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 204 B |
|
@ -1,30 +1,41 @@
|
|||
from helper import unittest, PillowTestCase, hopper
|
||||
from test_imageqt import PillowQtTestCase
|
||||
|
||||
from PIL import ImageQt
|
||||
from PIL import ImageQt, Image
|
||||
|
||||
|
||||
class TestFromQImage(PillowQtTestCase, PillowTestCase):
|
||||
|
||||
files_to_test = [
|
||||
hopper(),
|
||||
Image.open('Tests/images/transparent.png'),
|
||||
Image.open('Tests/images/7x13.png'),
|
||||
]
|
||||
|
||||
def roundtrip(self, expected):
|
||||
result = ImageQt.fromqimage(expected.toqimage())
|
||||
# Qt saves all images as rgb
|
||||
self.assert_image_equal(result, expected.convert('RGB'))
|
||||
|
||||
def test_sanity_1(self):
|
||||
self.roundtrip(hopper('1'))
|
||||
for im in self.files_to_test:
|
||||
self.roundtrip(im.convert('1'))
|
||||
|
||||
def test_sanity_rgb(self):
|
||||
self.roundtrip(hopper('RGB'))
|
||||
for im in self.files_to_test:
|
||||
self.roundtrip(im.convert('RGB'))
|
||||
|
||||
def test_sanity_rgba(self):
|
||||
self.roundtrip(hopper('RGBA'))
|
||||
for im in self.files_to_test:
|
||||
self.roundtrip(im.convert('RGBA'))
|
||||
|
||||
def test_sanity_l(self):
|
||||
self.roundtrip(hopper('L'))
|
||||
for im in self.files_to_test:
|
||||
self.roundtrip(im.convert('L'))
|
||||
|
||||
def test_sanity_p(self):
|
||||
self.roundtrip(hopper('P'))
|
||||
for im in self.files_to_test:
|
||||
self.roundtrip(im.convert('P'))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
Loading…
Reference in New Issue
Block a user