'How to setPixmap on a QLabel from QCamera image

I been trying an image to a Label via setPixmap() but to no avail... In fact, i want that if i click to call the Methode def click_photo(self): to setthe image also

from PyQt5.QtWidgets import *
from PyQt5.QtMultimedia import *
from PyQt5.QtMultimediaWidgets import *
import os, sys, time

class MainWindow(QMainWindow):   
    def __init__(self):   # constructor 
        super().__init__() 
        self.setGeometry(100, 100, 800, 600) 
        self.setStyleSheet("background : lightgrey;") 
        self.available_cameras = QCameraInfo.availableCameras()  

        self.Label_preview = QLabel(self, 'preview here')
        self.status = QStatusBar() 
        self.status.setStyleSheet("background : white;")   
        self.setStatusBar(self.status)         # adding status bar to the main window 
        self.save_path = "" # path to save 
        self.viewfinder = QCameraViewfinder()  # creating a QCameraViewfinder object 
        self.viewfinder.show() # showing this viewfinder 
        self.setCentralWidget(self.viewfinder)  # making it central widget of main window 
        
        self.select_camera(0) # Set the default camera. 
        toolbar = QToolBar("Camera Tool Bar") # creating a tool bar 
        self.addToolBar(toolbar) # adding tool bar to main window 
        click_action = QAction("Click photo", self) # creating a photo action to take photo 
        click_action.setStatusTip("This will capture picture") # adding status tip to the photo action 
        click_action.setToolTip("Capture picture") 
        click_action.triggered.connect(self.click_photo)  # adding action to it 
        toolbar.addAction(click_action) # adding this to the tool bar 
        change_folder_action = QAction("Change save location", self)  # similarly creating action for changing save folder 
        change_folder_action.setStatusTip("Change folder where picture will be saved saved.") 
        change_folder_action.setToolTip("Change save location")  # adding tool tip to it 

        # setting calling method to the change folder action 
        # when triggered signal is emitted 
        change_folder_action.triggered.connect(self.change_folder) 
        toolbar.addAction(change_folder_action) # adding this to the tool bar 


        # creating a combo box for selecting camera 
        camera_selector = QComboBox() 

        # adding status tip to it 
        camera_selector.setStatusTip("Choose camera to take pictures") 

        # adding tool tip to it 
        camera_selector.setToolTip("Select Camera") 
        camera_selector.setToolTipDuration(2500) 

        # adding items to the combo box 
        camera_selector.addItems([camera.description() 
                                for camera in self.available_cameras]) 

        # adding action to the combo box 
        # calling the select camera method 
        camera_selector.currentIndexChanged.connect(self.select_camera) 

        # adding this to tool bar 
        toolbar.addWidget(camera_selector) 
        toolbar.setStyleSheet("background : white;") 
        self.setWindowTitle("PyQt5 Cam") 
        self.show() 

    # method to select camera 
    def select_camera(self, i): 
        self.camera = QCamera(self.available_cameras[i])  # getting the selected camera 
        self.camera.setViewfinder(self.viewfinder) # getting the selected camera 
        self.camera.setCaptureMode(QCamera.CaptureStillImage) # setting capture mode to the camera 
        self.camera.error.connect(lambda: self.alert(self.camera.errorString())) # if any error occur show the alert 
        self.camera.start() # start the camera  
        self.capture = QCameraImageCapture(self.camera) # creating a QCameraImageCapture object
        self.capture.error.connect(lambda error_msg, error, msg: self.alert(msg))  # showing alert if error occur 
        self.capture.imageCaptured.connect(lambda d, 
                                        i: self.status.showMessage("Image captured : "
                                                                    + str(self.save_seq))) # when image captured showing message 
        self.capture.imageCaptured.connect(lambda d, i: self.status.showMessage("Image captured : " + str(self.save_seq))) # when image captured showing message 
        self.tipamu = i
        # getting current camera name 
        self.current_camera_name = self.available_cameras[i].description() 

        # inital save sequence 
        self.save_seq = 0

    # method to take photo 
    def click_photo(self): 
        # time stamp 
        timestamp = time.strftime("%d-%b-%Y-%H_%M_%S") 
        self.capture.capture(os.path.join(self.save_path,  
                                        "%s-%04d-%s.jpg" % ( 
            self.current_camera_name, 
            self.save_seq, 
            timestamp 
        ))) # capture the image and save it on the save path 

        # increment the sequence 
        self.save_seq += 1

    # change folder method 
    def change_folder(self): 
        path = QFileDialog.getExistingDirectory(self, "Picture Location", "")  # open the dialog to select path 
        if path: # if path is selected 
            self.save_path = path  # update the path 
            self.save_seq = 0   # update the sequence 

    def alert(self, msg): 
        error = QErrorMessage(self) # error message       
        error.showMessage(msg)  # setting text to the error message 

# Driver code 
if __name__ == "__main__" : 
    App = QApplication(sys.argv)  # create pyqt5 app 
    window = MainWindow()         # create the instance of our Window 
    sys.exit(App.exec())          # start the app 

i tried

self.Label_preview.setPixmap(QPixmap(self.capture))

but it didn't work, is there a way to approach this: setting the image captured via webcam to the preview Qlabel self.Label_preview before saving that image to the disk or without saving to the disk ?



Solution 1:[1]

I started from the same example you found. Here is how I did it with a bit of extra styling and ported to PyQt6.

# importing required libraries
from PyQt6.QtWidgets import *
from PyQt6.QtGui import *
from PyQt6.QtMultimedia import *
from PyQt6.QtMultimediaWidgets import *
from PyQt6.QtCore import Qt
import os
import sys
import time

stylesheet = """
QWidget {
    background-color: rgba(32.000, 33.000, 36.000, 1.000);
    color: rgba(170.000, 170.000, 170.000, 1.000);
    selection-background-color: rgba(138.000, 180.000, 247.000, 1.000);
    selection-color: rgba(32.000, 33.000, 36.000, 1.000);
}
QWidget:disabled {
    color: rgba(105.000, 113.000, 119.000, 1.000);
    selection-background-color: rgba(83.000, 87.000, 91.000, 1.000);
    selection-color: rgba(105.000, 113.000, 119.000, 1.000);
}
QToolTip {
    background-color: rgba(41.000, 42.000, 45.000, 1.000);
    color: rgba(228.000, 231.000, 235.000, 1.000);
    border: 1px solid rgba(63.000, 64.000, 66.000, 1.000);
}
QSizeGrip {
    width: 0;
    height: 0;
    image: none;
}
QStatusBar {
    background-color: rgba(42.000, 43.000, 46.000, 1.000);
}
QStatusBar::item {
    border: none;
}
QStatusBar QWidget {
    background-color: transparent;
    padding: 0px;
    border-radius: 0px;
    margin: 0px;
}
QStatusBar QWidget:pressed {
    background-color: rgba(79.000, 80.000, 84.000, 1.000);
}
QStatusBar QWidget:disabled {
    background-color: rgba(32.000, 33.000, 36.000, 1.000);
}
QStatusBar QWidget:checked {
    background-color: rgba(79.000, 80.000, 84.000, 1.000);
}
QToolBar {
    background-color: rgba(41.000, 42.000, 45.000, 1.000);
    padding: 1x;
    font-weight: bold;
    spacing: 1px;
    margin: 1px;
}
QToolBar::separator {
    background-color: rgba(63.000, 64.000, 66.000, 1.000);
}
QToolBar::separator:horizontal {
    width: 2px;
    margin: 0 6px;
}
QToolBar::separator:vertical {
    height: 2px;
    margin: 6px 0;
}
QPushButton {
    border: 1px solid rgba(63.000, 64.000, 66.000, 1.000);
    padding: 4px 8px;
    border-radius: 4px;
    color: rgba(138.000, 180.000, 247.000, 1.000);
}
QPushButton:hover {
    background-color: rgba(30.000, 43.000, 60.000, 1.000);
}
QPushButton:pressed {
    background-color: rgba(46.000, 70.000, 94.000, 1.000);
}
QPushButton:checked {
    border-color: rgba(138.000, 180.000, 247.000, 1.000);
}
QPushButton:disabled {
    border-color: rgba(63.000, 64.000, 66.000, 1.000);
}
QPushButton[flat=true]:!checked {
    border-color: transparent;
}
QDialogButtonBox QPushButton {
    min-width: 65px;
}
QComboBox {
    border: 1px solid rgba(63.000, 64.000, 66.000, 1.000);
    border-radius: 4px;
    min-height: 1.5em;
    padding: 0 4px;
    background-color: rgba(63.000, 64.000, 66.000, 1.000);
}
QComboBox:focus,
QComboBox:open {
    border: 1px solid rgba(138.000, 180.000, 247.000, 1.000);
}
QComboBox::drop-down {
    subcontrol-position: center right;
    border: none;
    padding-right: 4px;
}
QComboBox::item:selected {
    border: none;
    background-color: rgba(0.000, 72.000, 117.000, 1.000);
    color: rgba(228.000, 231.000, 235.000, 1.000);
}
QComboBox QAbstractItemView {
    margin: 0;
    border: 1px solid rgba(63.000, 64.000, 66.000, 1.000);
    selection-background-color: rgba(0.000, 72.000, 117.000, 1.000);
    selection-color: rgba(228.000, 231.000, 235.000, 1.000);
    padding: 2px;
}
"""


# Main window class
class MainWindow(QMainWindow):

    # constructor
    def __init__(self):
        super().__init__()

        self.captured_image = None
        self.save_seq = None
        self.capture = None
        self.camera = None
        self.current_camera_name = None
        self.mirror_h = True

        # setting geometry
        self.setGeometry(200, 200, 800, 600)
        self.setStyleSheet("background : darkgrey;")

        # getting available cameras
        self.available_cameras = QMediaDevices.videoInputs()
        # if no camera found
        if not self.available_cameras:
            # exit the code
            sys.exit()

        self.status = QStatusBar()
        self.setStatusBar(self.status)

        # path to save
        self.save_path = ""

        toolbar = QToolBar("Camera Tool Bar")
        self.addToolBar(toolbar)

        # creating a photo action to take photo
        click_action = QAction("Get Photo", self)
        click_action.setStatusTip("This will capture picture")
        click_action.setToolTip("Capture picture")
        click_action.triggered.connect(self.capture_picture)
        toolbar.addAction(click_action)

        # similarly creating action for changing save folder
        change_folder_action = QAction("Save location", self)
        change_folder_action.setStatusTip("Change folder where picture will be saved saved.")
        change_folder_action.setToolTip("Change save location")
        change_folder_action.triggered.connect(self.change_folder)
        toolbar.addAction(change_folder_action)

        # creating a combo box for selecting camera
        camera_selector = QComboBox()
        camera_selector.setStatusTip("Choose camera to take pictures")
        camera_selector.setToolTip("Select Camera")
        camera_selector.setToolTipDuration(2500)
        camera_selector.addItems([camera.description() for camera in self.available_cameras])
        camera_selector.currentIndexChanged.connect(self.select_camera)
        toolbar.addWidget(camera_selector)

        camera_mirror = QCheckBox("Mirror")
        camera_mirror.setChecked(True)
        camera_mirror.setStatusTip("Mirror the captured image horizontally")
        camera_mirror.setToolTip("Mirror Camera")
        camera_mirror.stateChanged.connect(self.on_mirror_changed)
        toolbar.addWidget(camera_mirror)

        # setting window title
        self.setWindowTitle("PyQt6 Cam")

        main_wdg = QWidget()
        layout = QVBoxLayout(main_wdg)

        glay = QGridLayout()
        glay.setRowStretch(0, 1)
        glay.setRowStretch(1, 0)
        self.label = QLabel()
        self.label.setSizePolicy(QSizePolicy.Policy.Ignored, QSizePolicy.Policy.Expanding)
        self.save_btn = QPushButton("Save Picture")
        self.save_btn.clicked.connect(self.on_save_picture)
        glay.addWidget(self.label, 0, 0)
        glay.addWidget(self.save_btn, 1, 0)

        self.video_wdg = QVideoWidget()

        hlay = QHBoxLayout()
        hlay.addLayout(glay)
        hlay.addWidget(self.video_wdg)

        layout.addLayout(hlay, stretch=1)

        self.setCentralWidget(main_wdg)
        self.video_wdg.show()

        # showing the main window
        self.show()
        self.select_camera(0)

    # method to select camera
    def select_camera(self, current_camera):
        media_capture_session = QMediaCaptureSession(self)
        self.camera = QCamera(self.available_cameras[current_camera])
        self.camera.start()

        media_capture_session.setCamera(self.camera)
        media_capture_session.setVideoOutput(self.video_wdg)

        self.camera.errorOccurred.connect(lambda err, err_str: self.alert(err_str))

        self.capture = QImageCapture(self.camera)
        media_capture_session.setImageCapture(self.capture)
        self.capture.errorOccurred.connect(lambda error_msg, error, msg: self.alert(msg))

        # when image captured showing message
        self.capture.imageCaptured.connect(self.on_image_captured)

        self.current_camera_name = self.available_cameras[current_camera].description()

        # initial save sequence
        self.save_seq = 0

    def on_image_captured(self, id, image):
        width = self.label.width()
        height = self.label.height()
        self.captured_image = image
        if self.mirror_h is True:
            self.captured_image = image.mirrored(horizontal=True, vertical=False)
        pixmap = QPixmap().fromImage(self.captured_image)

        self.label.setPixmap(pixmap.scaled(width, height, Qt.AspectRatioMode.KeepAspectRatio))
        self.status.showMessage("Image captured.")

    # method to take photo
    def capture_picture(self):
        self.capture.capture()

    def on_save_picture(self):
        # time stamp
        timestamp = time.strftime("%d-%b-%Y-%H_%M_%S")

        file_path = os.path.join(
            self.save_path, "%s-%04d-%s.jpg" % (self.current_camera_name, self.save_seq, timestamp))
        try:
            self.captured_image.save(file_path, format='jpg', quality=-1)
        except Exception as err:
            print(err)

        self.status.showMessage("Image saved to: %s" % str(file_path))
        # increment the sequence
        self.save_seq += 1

    def on_mirror_changed(self, state):
        self.mirror_h = True if int(state) else False

    # change folder method
    def change_folder(self):

        # open the dialog to select path
        path = QFileDialog.getExistingDirectory(self, "Picture Location", "")

        # if path is selected
        if path:
            # update the path
            self.save_path = path

            # update the sequence
            self.save_seq = 0

    # method for alerts
    def alert(self, msg):

        # error message
        error = QErrorMessage(self)

        # setting text to the error message
        error.showMessage(msg)


# Driver code
if __name__ == "__main__":
    # create pyqt5 app
    App = QApplication(sys.argv)

    # create the instance of our Window
    window = MainWindow()
    window.setStyleSheet(stylesheet)

    # start the app
    sys.exit(App.exec())

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 mars01