[PATCH 1/2] qcam: viewfinder_qt: Draw the letterbox background black
Kieran Bingham
kieran.bingham at ideasonboard.com
Mon Sep 9 14:33:54 CEST 2024
Quoting Laurent Pinchart (2024-09-05 17:25:07)
> When the widget's aspect ratio doesn't match the camera aspect ratio,
> the viewfinder is rendered letter-boxed. The side rectangles are not
> painted by the viewfinder, and Qt thus renders the parent widget
> background to fill that space.
>
> To make it black, we have two options:
>
> - The simplest option is to set the widget's autoFillBackground property
> to true. This causes Qt to paint the whole widget with its background
> colour before calling paintEvent(). As the camera image typically
> covers most (if not all) of the viewfinder widget, this is less
> efficient.
>
> - The more complicated option is to pain the letterbox rectangles
s/pain/paint/
> manually. We can additionally set the widget's WA_OpaquePaintEvent
> attribute to instruct Qt to skip painting the parent widget. This
> reduces CPU usage by about 1% (and may reduce GPU usage as well).
>
> Note that the WA_OpaquePaintEvent attribute has to be disabled when we
> render the stopped icon, as the icon has a transparent background.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> ---
> src/apps/qcam/viewfinder_qt.cpp | 23 +++++++++++++++++++++--
> 1 file changed, 21 insertions(+), 2 deletions(-)
>
> diff --git a/src/apps/qcam/viewfinder_qt.cpp b/src/apps/qcam/viewfinder_qt.cpp
> index 492648cfa2ff..62b6f27fa23e 100644
> --- a/src/apps/qcam/viewfinder_qt.cpp
> +++ b/src/apps/qcam/viewfinder_qt.cpp
> @@ -44,6 +44,10 @@ ViewFinderQt::ViewFinderQt(QWidget *parent)
> : QWidget(parent), place_(rect()), buffer_(nullptr)
> {
> icon_ = QIcon(":camera-off.svg");
> +
> + QPalette pal = palette();
> + pal.setColor(QPalette::Window, Qt::black);
> + setPalette(pal);
> }
>
> ViewFinderQt::~ViewFinderQt()
> @@ -118,6 +122,7 @@ void ViewFinderQt::render(libcamera::FrameBuffer *buffer, Image *image)
> }
> }
>
I would probably have a comment here ...
> + setAttribute(Qt::WA_OpaquePaintEvent, true);
> update();
>
> if (buffer)
> @@ -133,6 +138,7 @@ void ViewFinderQt::stop()
> buffer_ = nullptr;
> }
>
and here ...
to say why we are starting and sotpping the paint attributes.
> + setAttribute(Qt::WA_OpaquePaintEvent, false);
> update();
> }
>
> @@ -147,8 +153,22 @@ void ViewFinderQt::paintEvent(QPaintEvent *)
> {
> QPainter painter(this);
>
> - /* If we have an image, draw it. */
> + painter.setBrush(palette().window());
> +
> + /* If we have an image, draw it, with black letterbox rectangles. */
> if (!image_.isNull()) {
> + if (place_.width() < width()) {
> + QRect rect{ 0, 0, (width() - place_.width()) / 2, height() };
> + painter.drawRect(rect);
> + rect.moveLeft(place_.right());
> + painter.drawRect(rect);
> + } else {
> + QRect rect{ 0, 0, width(), (height() - place_.height()) / 2 };
> + painter.drawRect(rect);
> + rect.moveTop(place_.bottom());
> + painter.drawRect(rect);
> + }
Seems easy enough.
Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
And tested on my X13s
However, I can't currently test qcam -r gles it seems which is crashing
but that's on mainline too so not this series.
> +
> painter.drawImage(place_, image_, image_.rect());
> return;
> }
> @@ -174,7 +194,6 @@ void ViewFinderQt::paintEvent(QPaintEvent *)
> else
> point.setY((height() - pixmap_.height()) / 2);
>
> - painter.setBackgroundMode(Qt::OpaqueMode);
> painter.drawPixmap(point, pixmap_);
> }
>
> --
> Regards,
>
> Laurent Pinchart
>
More information about the libcamera-devel
mailing list