mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-11-15 14:17:13 +03:00
101 lines
3.5 KiB
Python
101 lines
3.5 KiB
Python
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
from typing import TYPE_CHECKING, Union
|
|
|
|
import pytest
|
|
|
|
from PIL import Image, ImageQt
|
|
|
|
from .helper import assert_image_equal_tofile, assert_image_similar, hopper
|
|
|
|
if TYPE_CHECKING:
|
|
import PyQt6
|
|
import PySide6
|
|
|
|
QApplication = Union[PyQt6.QtWidgets.QApplication, PySide6.QtWidgets.QApplication]
|
|
QHBoxLayout = Union[PyQt6.QtWidgets.QHBoxLayout, PySide6.QtWidgets.QHBoxLayout]
|
|
QImage = Union[PyQt6.QtGui.QImage, PySide6.QtGui.QImage]
|
|
QLabel = Union[PyQt6.QtWidgets.QLabel, PySide6.QtWidgets.QLabel]
|
|
QPainter = Union[PyQt6.QtGui.QPainter, PySide6.QtGui.QPainter]
|
|
QPixmap = Union[PyQt6.QtGui.QPixmap, PySide6.QtGui.QPixmap]
|
|
QPoint = Union[PyQt6.QtCore.QPoint, PySide6.QtCore.QPoint]
|
|
QRegion = Union[PyQt6.QtGui.QRegion, PySide6.QtGui.QRegion]
|
|
QWidget = Union[PyQt6.QtWidgets.QWidget, PySide6.QtWidgets.QWidget]
|
|
|
|
if ImageQt.qt_is_installed:
|
|
from PIL.ImageQt import QPixmap
|
|
|
|
if ImageQt.qt_version == "6":
|
|
from PyQt6.QtCore import QPoint
|
|
from PyQt6.QtGui import QImage, QPainter, QRegion
|
|
from PyQt6.QtWidgets import QApplication, QHBoxLayout, QLabel, QWidget
|
|
elif ImageQt.qt_version == "side6":
|
|
from PySide6.QtCore import QPoint
|
|
from PySide6.QtGui import QImage, QPainter, QRegion
|
|
from PySide6.QtWidgets import QApplication, QHBoxLayout, QLabel, QWidget
|
|
|
|
class Example(QWidget): # type: ignore[misc]
|
|
def __init__(self) -> None:
|
|
super().__init__()
|
|
|
|
img = hopper().resize((1000, 1000))
|
|
|
|
qimage = ImageQt.ImageQt(img)
|
|
|
|
pixmap1 = getattr(ImageQt.QPixmap, "fromImage")(qimage)
|
|
|
|
# hbox
|
|
QHBoxLayout(self) # type: ignore[operator]
|
|
|
|
lbl = QLabel(self) # type: ignore[operator]
|
|
# Segfault in the problem
|
|
lbl.setPixmap(pixmap1.copy())
|
|
|
|
|
|
def roundtrip(expected: Image.Image) -> None:
|
|
result = ImageQt.fromqpixmap(ImageQt.toqpixmap(expected))
|
|
# Qt saves all pixmaps as rgb
|
|
assert_image_similar(result, expected.convert("RGB"), 1)
|
|
|
|
|
|
@pytest.mark.skipif(not ImageQt.qt_is_installed, reason="Qt bindings are not installed")
|
|
def test_sanity(tmp_path: Path) -> None:
|
|
# Segfault test
|
|
app: QApplication | None = QApplication([]) # type: ignore[operator]
|
|
ex = Example()
|
|
assert app # Silence warning
|
|
assert ex # Silence warning
|
|
|
|
for mode in ("1", "RGB", "RGBA", "L", "P"):
|
|
# to QPixmap
|
|
im = hopper(mode)
|
|
data = ImageQt.toqpixmap(im)
|
|
|
|
assert data.__class__.__name__ == "QPixmap"
|
|
assert not data.isNull()
|
|
|
|
# Test saving the file
|
|
tempfile = str(tmp_path / f"temp_{mode}.png")
|
|
data.save(tempfile)
|
|
|
|
# Render the image
|
|
imageqt = ImageQt.ImageQt(im)
|
|
data = getattr(QPixmap, "fromImage")(imageqt)
|
|
qt_format = getattr(QImage, "Format") if ImageQt.qt_version == "6" else QImage
|
|
qimage = QImage(128, 128, getattr(qt_format, "Format_ARGB32")) # type: ignore[operator]
|
|
painter = QPainter(qimage) # type: ignore[operator]
|
|
image_label = QLabel() # type: ignore[operator]
|
|
image_label.setPixmap(data)
|
|
image_label.render(painter, QPoint(0, 0), QRegion(0, 0, 128, 128)) # type: ignore[operator]
|
|
painter.end()
|
|
rendered_tempfile = str(tmp_path / f"temp_rendered_{mode}.png")
|
|
qimage.save(rendered_tempfile)
|
|
assert_image_equal_tofile(im.convert("RGBA"), rendered_tempfile)
|
|
|
|
# from QPixmap
|
|
roundtrip(hopper(mode))
|
|
|
|
app.quit()
|
|
app = None
|