Merge pull request #1430 from ericfrederich/qt_align

bug fix: Qt wants data aligned to 32 bits
This commit is contained in:
wiredfool 2015-09-20 10:41:38 +01:00
commit 68dd0ac2cc
3 changed files with 45 additions and 7 deletions

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 B

View File

@ -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__':