0

Im trying to overlay an image with transparency on QCameraViewfinder. The following code works fine on windows, but ignores the transparency on raspberry pi.

Im using pyside2 version 5.11.2 on RPI4 and tried tranparent PNG and SVG files.

As an alternative, if Im using paintEvent to draw shapes, the viewfinder doesnt show video. My QPainter code is attached too.

from PySide2.QtMultimedia import QCamera, QCameraInfo
from PySide2.QtMultimediaWidgets import QCameraViewfinder

from PySide2 import QtCore, QtGui
from PySide2.QtWidgets import *
from PySide2.QtGui import *
from PySide2.QtCore import *
import sys

class ExampleWindow(QMainWindow):
    def __init__(self, windowsize):
        super().__init__()
        self.windowsize = windowsize
        self.initUI()

    def initUI(self):
        self.setFixedSize(self.windowsize)

        widget = QWidget()
        self.setCentralWidget(widget)

        self.view_finder = QCameraViewfinder()
        camerainfo = QCameraInfo.availableCameras()[0]
        self.camera = QCamera(camerainfo)
        self.camera.setViewfinder(self.view_finder)
        self.camera.start()
        
        layout_box = QHBoxLayout(widget)
        layout_box.setContentsMargins(0, 0, 0, 0)
        layout_box.addWidget(self.view_finder)

        pixmap = QPixmap('crosshair3.png')
        self.image = QLabel(widget)
        self.image.setPixmap(pixmap)
        self.image.setFixedSize(pixmap.size())

        hw = pixmap.size().width()/2
        hh = pixmap.size().height()/2

        self.image.move(self.rect().center().x()-hw, self.rect().center().y()-hh)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    screensize = app.desktop().availableGeometry().size()

    ex = ExampleWindow(screensize)
    ex.show()

sys.exit(app.exec_())

When using QPainter there is no video on the viewfinder:


class MyQCameraViewfinder(QCameraViewfinder):
    def __init__(self, parent=None):
        super().__init__(parent)
    
    def paintEvent(self, event):
        paint = QtGui.QPainter()
        paint.begin(self)

        paint.setRenderHint(QtGui.QPainter.Antialiasing)
        paint.setPen(QtCore.Qt.black)
        paint.setBrush(QtCore.Qt.white)   
        paint.drawEllipse(QtCore.QRect(17, 22, 50, 50)) 

        paint.end()    

on windows 11:on windows 11 on rpi 4:on rpi 4

ramiwi
  • 902
  • 2
  • 10
  • 28
  • 1
    QVideoWidget (which is inherited by QCameraViewFinder) is not a standard widget, and the "painting" of the video doesn't work like a QWidget, since Qt normally uses the underlying OS video displaying for that. Overriding the paint event (which should call the base implementation anyway, which you didn't) wouldn't change anything if the video uses overlay. You could try using [`setMask()`](//doc.qt.io/qt-5/qwidget.html#setMask) on the label, based on [`createHeuristicMask()`](//doc.qt.io/qt-5/qpixmap.html#createHeuristicMask) of the pixmap, but it wouldn't have antialiasing. – musicamante Aug 31 '22 at 20:37
  • 1
    The only *safe* solution is to use QGraphicsView with [QGraphicsVideoItem](https://doc.qt.io/qt-5/qgraphicsvideoitem.html). See this answer: https://stackoverflow.com/a/53900019 – musicamante Aug 31 '22 at 20:38
  • @musicamante is it possible to add QCamera view to a QGraphicsView object? – ramiwi Aug 31 '22 at 21:41
  • 1
    [`setViewfinder()`](https://doc.qt.io/qt-5/qcamera.html#setViewfinder-1) also accepts a QGraphicsVideoItem. Just use that instead of QCameraViewfinder, and add it to the scene. – musicamante Aug 31 '22 at 22:27
  • @musicamante It works! With QGraphicsVideoItem I can now use transparent overlays. Can the QGraphicsVideoItem window resize to fill the layout space as QCameraViewFinder did? And for some reason my scene works fine with PyQt5 but its empty when using PySide2. – ramiwi Sep 02 '22 at 18:31
  • 1
    I suggest you to create a separate question for that. – musicamante Sep 02 '22 at 21:21

0 Answers0