We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
ImageQt does not work as expected in PyQt5

### What did you do?

Attempted to use ImageQt to load a Pillow image in a PyQt5 application

### What did you expect to happen?

I expected the image to load correctly. There are no errors, but it does not load the image in PyQt5 correctly.

### What actually happened?

The image loaded as a mostly white image with kind of ghost image of the actual photo (see screenshot). I have attached the PyQt5 and PySide6 code, including screenshots from when I ran both files.

**Note: The same code works in PySide6, but not in PyQt5.**

### What are your OS, Python and Pillow versions?

* OS: MacOS Mojave and Windows 10
* Python: Python 3.9
* Pillow: 8.0.0
![pink_flower](https://user-images.githubusercontent.com/2895418/107862335-d27f7580-6e11-11eb-9cf9-d4a19d2d615b.jpg)




<!--
Please include **code** that reproduces the issue and whenever possible, an **image** that demonstrates the issue. Please upload images to GitHub, not to third-party file hosting sites. If necessary, add the image to a zip or tar archive.

The best reproductions are self-contained scripts with minimal dependencies. If you are using a framework such as Plone, Django, or Buildout, try to replicate the issue just using Pillow.
-->

```python
import sys

from PIL import Image, ImageQt
from PyQt5.QtGui import QPixmap, QImage
from PyQt5.QtWidgets import QWidget, QLabel
from PyQt5.QtWidgets import QVBoxLayout, QApplication


class ImageViewer(QWidget):

    def __init__(self):
        QWidget.__init__(self)
        self.setWindowTitle("PyQt Image Viewer")

        # Open up image in Pillow
        image = Image.open("pink_flower.jpg")
        qt_image = ImageQt.ImageQt(image)
        pixmap = QPixmap.fromImage(qt_image)

        self.image_label = QLabel('')
        self.image_label.setPixmap(pixmap)

        self.main_layout = QVBoxLayout()
        self.main_layout.addWidget(self.image_label)
        self.setLayout(self.main_layout)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    viewer = ImageViewer()
    viewer.show()
    app.exec_()
```

[pyqt_pillow_issue.zip](https://github.com/python-pillow/Pillow/files/5976581/pyqt_pillow_issue.zip)

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/PIL/ImageQt.py`
Content:
```
1 #
2 # The Python Imaging Library.
3 # $Id$
4 #
5 # a simple Qt image interface.
6 #
7 # history:
8 # 2006-06-03 fl: created
9 # 2006-06-04 fl: inherit from QImage instead of wrapping it
10 # 2006-06-05 fl: removed toimage helper; move string support to ImageQt
11 # 2013-11-13 fl: add support for Qt5 (aurelien.ballier@cyclonit.com)
12 #
13 # Copyright (c) 2006 by Secret Labs AB
14 # Copyright (c) 2006 by Fredrik Lundh
15 #
16 # See the README file for information on usage and redistribution.
17 #
18 
19 import sys
20 from io import BytesIO
21 
22 from . import Image
23 from ._util import isPath
24 
25 qt_versions = [
26     ["6", "PyQt6"],
27     ["side6", "PySide6"],
28     ["5", "PyQt5"],
29     ["side2", "PySide2"],
30 ]
31 
32 # If a version has already been imported, attempt it first
33 qt_versions.sort(key=lambda qt_version: qt_version[1] in sys.modules, reverse=True)
34 for qt_version, qt_module in qt_versions:
35     try:
36         if qt_module == "PyQt6":
37             from PyQt6.QtCore import QBuffer, QIODevice
38             from PyQt6.QtGui import QImage, QPixmap, qRgba
39         elif qt_module == "PySide6":
40             from PySide6.QtCore import QBuffer, QIODevice
41             from PySide6.QtGui import QImage, QPixmap, qRgba
42         elif qt_module == "PyQt5":
43             from PyQt5.QtCore import QBuffer, QIODevice
44             from PyQt5.QtGui import QImage, QPixmap, qRgba
45         elif qt_module == "PySide2":
46             from PySide2.QtCore import QBuffer, QIODevice
47             from PySide2.QtGui import QImage, QPixmap, qRgba
48     except (ImportError, RuntimeError):
49         continue
50     qt_is_installed = True
51     break
52 else:
53     qt_is_installed = False
54     qt_version = None
55 
56 
57 def rgb(r, g, b, a=255):
58     """(Internal) Turns an RGB color into a Qt compatible color integer."""
59     # use qRgb to pack the colors, and then turn the resulting long
60     # into a negative integer with the same bitpattern.
61     return qRgba(r, g, b, a) & 0xFFFFFFFF
62 
63 
64 def fromqimage(im):
65     """
66     :param im: QImage or PIL ImageQt object
67     """
68     buffer = QBuffer()
69     qt_openmode = QIODevice.OpenMode if qt_version == "6" else QIODevice
70     buffer.open(qt_openmode.ReadWrite)
71     # preserve alpha channel with png
72     # otherwise ppm is more friendly with Image.open
73     if im.hasAlphaChannel():
74         im.save(buffer, "png")
75     else:
76         im.save(buffer, "ppm")
77 
78     b = BytesIO()
79     b.write(buffer.data())
80     buffer.close()
81     b.seek(0)
82 
83     return Image.open(b)
84 
85 
86 def fromqpixmap(im):
87     return fromqimage(im)
88     # buffer = QBuffer()
89     # buffer.open(QIODevice.ReadWrite)
90     # # im.save(buffer)
91     # # What if png doesn't support some image features like animation?
92     # im.save(buffer, 'ppm')
93     # bytes_io = BytesIO()
94     # bytes_io.write(buffer.data())
95     # buffer.close()
96     # bytes_io.seek(0)
97     # return Image.open(bytes_io)
98 
99 
100 def align8to32(bytes, width, mode):
101     """
102     converts each scanline of data from 8 bit to 32 bit aligned
103     """
104 
105     bits_per_pixel = {"1": 1, "L": 8, "P": 8}[mode]
106 
107     # calculate bytes per line and the extra padding if needed
108     bits_per_line = bits_per_pixel * width
109     full_bytes_per_line, remaining_bits_per_line = divmod(bits_per_line, 8)
110     bytes_per_line = full_bytes_per_line + (1 if remaining_bits_per_line else 0)
111 
112     extra_padding = -bytes_per_line % 4
113 
114     # already 32 bit aligned by luck
115     if not extra_padding:
116         return bytes
117 
118     new_data = []
119     for i in range(len(bytes) // bytes_per_line):
120         new_data.append(
121             bytes[i * bytes_per_line : (i + 1) * bytes_per_line]
122             + b"\x00" * extra_padding
123         )
124 
125     return b"".join(new_data)
126 
127 
128 def _toqclass_helper(im):
129     data = None
130     colortable = None
131     exclusive_fp = False
132 
133     # handle filename, if given instead of image name
134     if hasattr(im, "toUtf8"):
135         # FIXME - is this really the best way to do this?
136         im = str(im.toUtf8(), "utf-8")
137     if isPath(im):
138         im = Image.open(im)
139         exclusive_fp = True
140 
141     qt_format = QImage.Format if qt_version == "6" else QImage
142     if im.mode == "1":
143         format = qt_format.Format_Mono
144     elif im.mode == "L":
145         format = qt_format.Format_Indexed8
146         colortable = []
147         for i in range(256):
148             colortable.append(rgb(i, i, i))
149     elif im.mode == "P":
150         format = qt_format.Format_Indexed8
151         colortable = []
152         palette = im.getpalette()
153         for i in range(0, len(palette), 3):
154             colortable.append(rgb(*palette[i : i + 3]))
155     elif im.mode == "RGB":
156         data = im.tobytes("raw", "BGRX")
157         format = qt_format.Format_RGB32
158     elif im.mode == "RGBA":
159         data = im.tobytes("raw", "BGRA")
160         format = qt_format.Format_ARGB32
161     else:
162         if exclusive_fp:
163             im.close()
164         raise ValueError(f"unsupported image mode {repr(im.mode)}")
165 
166     size = im.size
167     __data = data or align8to32(im.tobytes(), size[0], im.mode)
168     if exclusive_fp:
169         im.close()
170     return {"data": __data, "size": size, "format": format, "colortable": colortable}
171 
172 
173 if qt_is_installed:
174 
175     class ImageQt(QImage):
176         def __init__(self, im):
177             """
178             An PIL image wrapper for Qt.  This is a subclass of PyQt's QImage
179             class.
180 
181             :param im: A PIL Image object, or a file name (given either as
182                 Python string or a PyQt string object).
183             """
184             im_data = _toqclass_helper(im)
185             # must keep a reference, or Qt will crash!
186             # All QImage constructors that take data operate on an existing
187             # buffer, so this buffer has to hang on for the life of the image.
188             # Fixes https://github.com/python-pillow/Pillow/issues/1370
189             self.__data = im_data["data"]
190             super().__init__(
191                 self.__data,
192                 im_data["size"][0],
193                 im_data["size"][1],
194                 im_data["format"],
195             )
196             if im_data["colortable"]:
197                 self.setColorTable(im_data["colortable"])
198 
199 
200 def toqimage(im):
201     return ImageQt(im)
202 
203 
204 def toqpixmap(im):
205     # # This doesn't work. For now using a dumb approach.
206     # im_data = _toqclass_helper(im)
207     # result = QPixmap(im_data["size"][0], im_data["size"][1])
208     # result.loadFromData(im_data["data"])
209     # Fix some strange bug that causes
210     if im.mode == "RGB":
211         im = im.convert("RGBA")
212 
213     qimage = toqimage(im)
214     return QPixmap.fromImage(qimage)
215
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/PIL/ImageQt.py b/src/PIL/ImageQt.py
--- a/src/PIL/ImageQt.py
+++ b/src/PIL/ImageQt.py
@@ -153,7 +153,10 @@
         for i in range(0, len(palette), 3):
             colortable.append(rgb(*palette[i : i + 3]))
     elif im.mode == "RGB":
-        data = im.tobytes("raw", "BGRX")
+        # Populate the 4th channel with 255
+        im = im.convert("RGBA")
+
+        data = im.tobytes("raw", "BGRA")
         format = qt_format.Format_RGB32
     elif im.mode == "RGBA":
         data = im.tobytes("raw", "BGRA")
@@ -206,9 +209,5 @@
     # im_data = _toqclass_helper(im)
     # result = QPixmap(im_data["size"][0], im_data["size"][1])
     # result.loadFromData(im_data["data"])
-    # Fix some strange bug that causes
-    if im.mode == "RGB":
-        im = im.convert("RGBA")
-
     qimage = toqimage(im)
     return QPixmap.fromImage(qimage)

{"golden_diff": "diff --git a/src/PIL/ImageQt.py b/src/PIL/ImageQt.py\n--- a/src/PIL/ImageQt.py\n+++ b/src/PIL/ImageQt.py\n@@ -153,7 +153,10 @@\n         for i in range(0, len(palette), 3):\n             colortable.append(rgb(*palette[i : i + 3]))\n     elif im.mode == \"RGB\":\n-        data = im.tobytes(\"raw\", \"BGRX\")\n+        # Populate the 4th channel with 255\n+        im = im.convert(\"RGBA\")\n+\n+        data = im.tobytes(\"raw\", \"BGRA\")\n         format = qt_format.Format_RGB32\n     elif im.mode == \"RGBA\":\n         data = im.tobytes(\"raw\", \"BGRA\")\n@@ -206,9 +209,5 @@\n     # im_data = _toqclass_helper(im)\n     # result = QPixmap(im_data[\"size\"][0], im_data[\"size\"][1])\n     # result.loadFromData(im_data[\"data\"])\n-    # Fix some strange bug that causes\n-    if im.mode == \"RGB\":\n-        im = im.convert(\"RGBA\")\n-\n     qimage = toqimage(im)\n     return QPixmap.fromImage(qimage)\n", "issue": "ImageQt does not work as expected in PyQt5\n\r\n### What did you do?\r\n\r\nAttempted to use ImageQt to load a Pillow image in a PyQt5 application\r\n\r\n### What did you expect to happen?\r\n\r\nI expected the image to load correctly. There are no errors, but it does not load the image in PyQt5 correctly.\r\n\r\n### What actually happened?\r\n\r\nThe image loaded as a mostly white image with kind of ghost image of the actual photo (see screenshot). I have attached the PyQt5 and PySide6 code, including screenshots from when I ran both files.\r\n\r\n**Note: The same code works in PySide6, but not in PyQt5.**\r\n\r\n### What are your OS, Python and Pillow versions?\r\n\r\n* OS: MacOS Mojave and Windows 10\r\n* Python: Python 3.9\r\n* Pillow: 8.0.0\r\n![pink_flower](https://user-images.githubusercontent.com/2895418/107862335-d27f7580-6e11-11eb-9cf9-d4a19d2d615b.jpg)\r\n\r\n\r\n\r\n\r\n<!--\r\nPlease include **code** that reproduces the issue and whenever possible, an **image** that demonstrates the issue. Please upload images to GitHub, not to third-party file hosting sites. If necessary, add the image to a zip or tar archive.\r\n\r\nThe best reproductions are self-contained scripts with minimal dependencies. If you are using a framework such as Plone, Django, or Buildout, try to replicate the issue just using Pillow.\r\n-->\r\n\r\n```python\r\nimport sys\r\n\r\nfrom PIL import Image, ImageQt\r\nfrom PyQt5.QtGui import QPixmap, QImage\r\nfrom PyQt5.QtWidgets import QWidget, QLabel\r\nfrom PyQt5.QtWidgets import QVBoxLayout, QApplication\r\n\r\n\r\nclass ImageViewer(QWidget):\r\n\r\n    def __init__(self):\r\n        QWidget.__init__(self)\r\n        self.setWindowTitle(\"PyQt Image Viewer\")\r\n\r\n        # Open up image in Pillow\r\n        image = Image.open(\"pink_flower.jpg\")\r\n        qt_image = ImageQt.ImageQt(image)\r\n        pixmap = QPixmap.fromImage(qt_image)\r\n\r\n        self.image_label = QLabel('')\r\n        self.image_label.setPixmap(pixmap)\r\n\r\n        self.main_layout = QVBoxLayout()\r\n        self.main_layout.addWidget(self.image_label)\r\n        self.setLayout(self.main_layout)\r\n\r\n\r\nif __name__ == \"__main__\":\r\n    app = QApplication(sys.argv)\r\n    viewer = ImageViewer()\r\n    viewer.show()\r\n    app.exec_()\r\n```\r\n\r\n[pyqt_pillow_issue.zip](https://github.com/python-pillow/Pillow/files/5976581/pyqt_pillow_issue.zip)\n", "before_files": [{"content": "#\n# The Python Imaging Library.\n# $Id$\n#\n# a simple Qt image interface.\n#\n# history:\n# 2006-06-03 fl: created\n# 2006-06-04 fl: inherit from QImage instead of wrapping it\n# 2006-06-05 fl: removed toimage helper; move string support to ImageQt\n# 2013-11-13 fl: add support for Qt5 (aurelien.ballier@cyclonit.com)\n#\n# Copyright (c) 2006 by Secret Labs AB\n# Copyright (c) 2006 by Fredrik Lundh\n#\n# See the README file for information on usage and redistribution.\n#\n\nimport sys\nfrom io import BytesIO\n\nfrom . import Image\nfrom ._util import isPath\n\nqt_versions = [\n    [\"6\", \"PyQt6\"],\n    [\"side6\", \"PySide6\"],\n    [\"5\", \"PyQt5\"],\n    [\"side2\", \"PySide2\"],\n]\n\n# If a version has already been imported, attempt it first\nqt_versions.sort(key=lambda qt_version: qt_version[1] in sys.modules, reverse=True)\nfor qt_version, qt_module in qt_versions:\n    try:\n        if qt_module == \"PyQt6\":\n            from PyQt6.QtCore import QBuffer, QIODevice\n            from PyQt6.QtGui import QImage, QPixmap, qRgba\n        elif qt_module == \"PySide6\":\n            from PySide6.QtCore import QBuffer, QIODevice\n            from PySide6.QtGui import QImage, QPixmap, qRgba\n        elif qt_module == \"PyQt5\":\n            from PyQt5.QtCore import QBuffer, QIODevice\n            from PyQt5.QtGui import QImage, QPixmap, qRgba\n        elif qt_module == \"PySide2\":\n            from PySide2.QtCore import QBuffer, QIODevice\n            from PySide2.QtGui import QImage, QPixmap, qRgba\n    except (ImportError, RuntimeError):\n        continue\n    qt_is_installed = True\n    break\nelse:\n    qt_is_installed = False\n    qt_version = None\n\n\ndef rgb(r, g, b, a=255):\n    \"\"\"(Internal) Turns an RGB color into a Qt compatible color integer.\"\"\"\n    # use qRgb to pack the colors, and then turn the resulting long\n    # into a negative integer with the same bitpattern.\n    return qRgba(r, g, b, a) & 0xFFFFFFFF\n\n\ndef fromqimage(im):\n    \"\"\"\n    :param im: QImage or PIL ImageQt object\n    \"\"\"\n    buffer = QBuffer()\n    qt_openmode = QIODevice.OpenMode if qt_version == \"6\" else QIODevice\n    buffer.open(qt_openmode.ReadWrite)\n    # preserve alpha channel with png\n    # otherwise ppm is more friendly with Image.open\n    if im.hasAlphaChannel():\n        im.save(buffer, \"png\")\n    else:\n        im.save(buffer, \"ppm\")\n\n    b = BytesIO()\n    b.write(buffer.data())\n    buffer.close()\n    b.seek(0)\n\n    return Image.open(b)\n\n\ndef fromqpixmap(im):\n    return fromqimage(im)\n    # buffer = QBuffer()\n    # buffer.open(QIODevice.ReadWrite)\n    # # im.save(buffer)\n    # # What if png doesn't support some image features like animation?\n    # im.save(buffer, 'ppm')\n    # bytes_io = BytesIO()\n    # bytes_io.write(buffer.data())\n    # buffer.close()\n    # bytes_io.seek(0)\n    # return Image.open(bytes_io)\n\n\ndef align8to32(bytes, width, mode):\n    \"\"\"\n    converts each scanline of data from 8 bit to 32 bit aligned\n    \"\"\"\n\n    bits_per_pixel = {\"1\": 1, \"L\": 8, \"P\": 8}[mode]\n\n    # calculate bytes per line and the extra padding if needed\n    bits_per_line = bits_per_pixel * width\n    full_bytes_per_line, remaining_bits_per_line = divmod(bits_per_line, 8)\n    bytes_per_line = full_bytes_per_line + (1 if remaining_bits_per_line else 0)\n\n    extra_padding = -bytes_per_line % 4\n\n    # already 32 bit aligned by luck\n    if not extra_padding:\n        return bytes\n\n    new_data = []\n    for i in range(len(bytes) // bytes_per_line):\n        new_data.append(\n            bytes[i * bytes_per_line : (i + 1) * bytes_per_line]\n            + b\"\\x00\" * extra_padding\n        )\n\n    return b\"\".join(new_data)\n\n\ndef _toqclass_helper(im):\n    data = None\n    colortable = None\n    exclusive_fp = False\n\n    # handle filename, if given instead of image name\n    if hasattr(im, \"toUtf8\"):\n        # FIXME - is this really the best way to do this?\n        im = str(im.toUtf8(), \"utf-8\")\n    if isPath(im):\n        im = Image.open(im)\n        exclusive_fp = True\n\n    qt_format = QImage.Format if qt_version == \"6\" else QImage\n    if im.mode == \"1\":\n        format = qt_format.Format_Mono\n    elif im.mode == \"L\":\n        format = qt_format.Format_Indexed8\n        colortable = []\n        for i in range(256):\n            colortable.append(rgb(i, i, i))\n    elif im.mode == \"P\":\n        format = qt_format.Format_Indexed8\n        colortable = []\n        palette = im.getpalette()\n        for i in range(0, len(palette), 3):\n            colortable.append(rgb(*palette[i : i + 3]))\n    elif im.mode == \"RGB\":\n        data = im.tobytes(\"raw\", \"BGRX\")\n        format = qt_format.Format_RGB32\n    elif im.mode == \"RGBA\":\n        data = im.tobytes(\"raw\", \"BGRA\")\n        format = qt_format.Format_ARGB32\n    else:\n        if exclusive_fp:\n            im.close()\n        raise ValueError(f\"unsupported image mode {repr(im.mode)}\")\n\n    size = im.size\n    __data = data or align8to32(im.tobytes(), size[0], im.mode)\n    if exclusive_fp:\n        im.close()\n    return {\"data\": __data, \"size\": size, \"format\": format, \"colortable\": colortable}\n\n\nif qt_is_installed:\n\n    class ImageQt(QImage):\n        def __init__(self, im):\n            \"\"\"\n            An PIL image wrapper for Qt.  This is a subclass of PyQt's QImage\n            class.\n\n            :param im: A PIL Image object, or a file name (given either as\n                Python string or a PyQt string object).\n            \"\"\"\n            im_data = _toqclass_helper(im)\n            # must keep a reference, or Qt will crash!\n            # All QImage constructors that take data operate on an existing\n            # buffer, so this buffer has to hang on for the life of the image.\n            # Fixes https://github.com/python-pillow/Pillow/issues/1370\n            self.__data = im_data[\"data\"]\n            super().__init__(\n                self.__data,\n                im_data[\"size\"][0],\n                im_data[\"size\"][1],\n                im_data[\"format\"],\n            )\n            if im_data[\"colortable\"]:\n                self.setColorTable(im_data[\"colortable\"])\n\n\ndef toqimage(im):\n    return ImageQt(im)\n\n\ndef toqpixmap(im):\n    # # This doesn't work. For now using a dumb approach.\n    # im_data = _toqclass_helper(im)\n    # result = QPixmap(im_data[\"size\"][0], im_data[\"size\"][1])\n    # result.loadFromData(im_data[\"data\"])\n    # Fix some strange bug that causes\n    if im.mode == \"RGB\":\n        im = im.convert(\"RGBA\")\n\n    qimage = toqimage(im)\n    return QPixmap.fromImage(qimage)\n", "path": "src/PIL/ImageQt.py"}], "after_files": [{"content": "#\n# The Python Imaging Library.\n# $Id$\n#\n# a simple Qt image interface.\n#\n# history:\n# 2006-06-03 fl: created\n# 2006-06-04 fl: inherit from QImage instead of wrapping it\n# 2006-06-05 fl: removed toimage helper; move string support to ImageQt\n# 2013-11-13 fl: add support for Qt5 (aurelien.ballier@cyclonit.com)\n#\n# Copyright (c) 2006 by Secret Labs AB\n# Copyright (c) 2006 by Fredrik Lundh\n#\n# See the README file for information on usage and redistribution.\n#\n\nimport sys\nfrom io import BytesIO\n\nfrom . import Image\nfrom ._util import isPath\n\nqt_versions = [\n    [\"6\", \"PyQt6\"],\n    [\"side6\", \"PySide6\"],\n    [\"5\", \"PyQt5\"],\n    [\"side2\", \"PySide2\"],\n]\n\n# If a version has already been imported, attempt it first\nqt_versions.sort(key=lambda qt_version: qt_version[1] in sys.modules, reverse=True)\nfor qt_version, qt_module in qt_versions:\n    try:\n        if qt_module == \"PyQt6\":\n            from PyQt6.QtCore import QBuffer, QIODevice\n            from PyQt6.QtGui import QImage, QPixmap, qRgba\n        elif qt_module == \"PySide6\":\n            from PySide6.QtCore import QBuffer, QIODevice\n            from PySide6.QtGui import QImage, QPixmap, qRgba\n        elif qt_module == \"PyQt5\":\n            from PyQt5.QtCore import QBuffer, QIODevice\n            from PyQt5.QtGui import QImage, QPixmap, qRgba\n        elif qt_module == \"PySide2\":\n            from PySide2.QtCore import QBuffer, QIODevice\n            from PySide2.QtGui import QImage, QPixmap, qRgba\n    except (ImportError, RuntimeError):\n        continue\n    qt_is_installed = True\n    break\nelse:\n    qt_is_installed = False\n    qt_version = None\n\n\ndef rgb(r, g, b, a=255):\n    \"\"\"(Internal) Turns an RGB color into a Qt compatible color integer.\"\"\"\n    # use qRgb to pack the colors, and then turn the resulting long\n    # into a negative integer with the same bitpattern.\n    return qRgba(r, g, b, a) & 0xFFFFFFFF\n\n\ndef fromqimage(im):\n    \"\"\"\n    :param im: QImage or PIL ImageQt object\n    \"\"\"\n    buffer = QBuffer()\n    qt_openmode = QIODevice.OpenMode if qt_version == \"6\" else QIODevice\n    buffer.open(qt_openmode.ReadWrite)\n    # preserve alpha channel with png\n    # otherwise ppm is more friendly with Image.open\n    if im.hasAlphaChannel():\n        im.save(buffer, \"png\")\n    else:\n        im.save(buffer, \"ppm\")\n\n    b = BytesIO()\n    b.write(buffer.data())\n    buffer.close()\n    b.seek(0)\n\n    return Image.open(b)\n\n\ndef fromqpixmap(im):\n    return fromqimage(im)\n    # buffer = QBuffer()\n    # buffer.open(QIODevice.ReadWrite)\n    # # im.save(buffer)\n    # # What if png doesn't support some image features like animation?\n    # im.save(buffer, 'ppm')\n    # bytes_io = BytesIO()\n    # bytes_io.write(buffer.data())\n    # buffer.close()\n    # bytes_io.seek(0)\n    # return Image.open(bytes_io)\n\n\ndef align8to32(bytes, width, mode):\n    \"\"\"\n    converts each scanline of data from 8 bit to 32 bit aligned\n    \"\"\"\n\n    bits_per_pixel = {\"1\": 1, \"L\": 8, \"P\": 8}[mode]\n\n    # calculate bytes per line and the extra padding if needed\n    bits_per_line = bits_per_pixel * width\n    full_bytes_per_line, remaining_bits_per_line = divmod(bits_per_line, 8)\n    bytes_per_line = full_bytes_per_line + (1 if remaining_bits_per_line else 0)\n\n    extra_padding = -bytes_per_line % 4\n\n    # already 32 bit aligned by luck\n    if not extra_padding:\n        return bytes\n\n    new_data = []\n    for i in range(len(bytes) // bytes_per_line):\n        new_data.append(\n            bytes[i * bytes_per_line : (i + 1) * bytes_per_line]\n            + b\"\\x00\" * extra_padding\n        )\n\n    return b\"\".join(new_data)\n\n\ndef _toqclass_helper(im):\n    data = None\n    colortable = None\n    exclusive_fp = False\n\n    # handle filename, if given instead of image name\n    if hasattr(im, \"toUtf8\"):\n        # FIXME - is this really the best way to do this?\n        im = str(im.toUtf8(), \"utf-8\")\n    if isPath(im):\n        im = Image.open(im)\n        exclusive_fp = True\n\n    qt_format = QImage.Format if qt_version == \"6\" else QImage\n    if im.mode == \"1\":\n        format = qt_format.Format_Mono\n    elif im.mode == \"L\":\n        format = qt_format.Format_Indexed8\n        colortable = []\n        for i in range(256):\n            colortable.append(rgb(i, i, i))\n    elif im.mode == \"P\":\n        format = qt_format.Format_Indexed8\n        colortable = []\n        palette = im.getpalette()\n        for i in range(0, len(palette), 3):\n            colortable.append(rgb(*palette[i : i + 3]))\n    elif im.mode == \"RGB\":\n        # Populate the 4th channel with 255\n        im = im.convert(\"RGBA\")\n\n        data = im.tobytes(\"raw\", \"BGRA\")\n        format = qt_format.Format_RGB32\n    elif im.mode == \"RGBA\":\n        data = im.tobytes(\"raw\", \"BGRA\")\n        format = qt_format.Format_ARGB32\n    else:\n        if exclusive_fp:\n            im.close()\n        raise ValueError(f\"unsupported image mode {repr(im.mode)}\")\n\n    size = im.size\n    __data = data or align8to32(im.tobytes(), size[0], im.mode)\n    if exclusive_fp:\n        im.close()\n    return {\"data\": __data, \"size\": size, \"format\": format, \"colortable\": colortable}\n\n\nif qt_is_installed:\n\n    class ImageQt(QImage):\n        def __init__(self, im):\n            \"\"\"\n            An PIL image wrapper for Qt.  This is a subclass of PyQt's QImage\n            class.\n\n            :param im: A PIL Image object, or a file name (given either as\n                Python string or a PyQt string object).\n            \"\"\"\n            im_data = _toqclass_helper(im)\n            # must keep a reference, or Qt will crash!\n            # All QImage constructors that take data operate on an existing\n            # buffer, so this buffer has to hang on for the life of the image.\n            # Fixes https://github.com/python-pillow/Pillow/issues/1370\n            self.__data = im_data[\"data\"]\n            super().__init__(\n                self.__data,\n                im_data[\"size\"][0],\n                im_data[\"size\"][1],\n                im_data[\"format\"],\n            )\n            if im_data[\"colortable\"]:\n                self.setColorTable(im_data[\"colortable\"])\n\n\ndef toqimage(im):\n    return ImageQt(im)\n\n\ndef toqpixmap(im):\n    # # This doesn't work. For now using a dumb approach.\n    # im_data = _toqclass_helper(im)\n    # result = QPixmap(im_data[\"size\"][0], im_data[\"size\"][1])\n    # result.loadFromData(im_data[\"data\"])\n    qimage = toqimage(im)\n    return QPixmap.fromImage(qimage)\n", "path": "src/PIL/ImageQt.py"}]}