py: cam: Drop PIL dependency

We can use Qt directly to accomplish the same as we do with PIL.

A minor downside is that loading MJPEG frame with Qt produces a "Corrupt
JPEG data" warning. The resulting picture looks fine, though. So add a
message handler to ignore that warning.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
Tomi Valkeinen 2022-05-30 17:27:10 +03:00 committed by Laurent Pinchart
parent 0971ea7c8b
commit 7330474762

View file

@ -2,18 +2,32 @@
# Copyright (C) 2022, Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> # Copyright (C) 2022, Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
from helpers import mfb_to_rgb from helpers import mfb_to_rgb
from io import BytesIO
from PIL import Image
from PIL.ImageQt import ImageQt
from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5 import QtCore, QtGui, QtWidgets
import libcamera as libcam import libcamera as libcam
import libcamera.utils import libcamera.utils
import sys import sys
# Loading MJPEG to a QPixmap produces corrupt JPEG data warnings. Ignore these.
def qt_message_handler(msg_type, msg_log_context, msg_string):
if msg_string.startswith("Corrupt JPEG data"):
return
# For some reason qInstallMessageHandler returns None, so we won't
# call the old handler
if old_msg_handler is not None:
old_msg_handler(msg_type, msg_log_context, msg_string)
else:
print(msg_string)
old_msg_handler = QtCore.qInstallMessageHandler(qt_message_handler)
def rgb_to_pix(rgb): def rgb_to_pix(rgb):
img = Image.frombuffer('RGB', (rgb.shape[1], rgb.shape[0]), rgb) w = rgb.shape[1]
qim = ImageQt(img).copy() h = rgb.shape[0]
qim = QtGui.QImage(rgb, w, h, QtGui.QImage.Format.Format_RGB888)
pix = QtGui.QPixmap.fromImage(qim) pix = QtGui.QPixmap.fromImage(qim)
return pix return pix
@ -136,9 +150,8 @@ class MainWindow(QtWidgets.QWidget):
cfg = stream.configuration cfg = stream.configuration
if cfg.pixel_format == libcam.formats.MJPEG: if cfg.pixel_format == libcam.formats.MJPEG:
img = Image.open(BytesIO(mfb.planes[0])) pix = QtGui.QPixmap(cfg.size.width, cfg.size.height)
qim = ImageQt(img).copy() pix.loadFromData(mfb.planes[0])
pix = QtGui.QPixmap.fromImage(qim)
else: else:
rgb = mfb_to_rgb(mfb, cfg) rgb = mfb_to_rgb(mfb, cfg)
if rgb is None: if rgb is None: