mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-24 17:15:07 +03:00
qcam: viewfinder_qt: Draw the letterbox background black
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 paint the letterbox rectangles 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@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
parent
e5fd3bea77
commit
2e2aa40799
1 changed files with 29 additions and 2 deletions
|
@ -40,6 +40,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()
|
||||
|
@ -114,6 +118,11 @@ void ViewFinderQt::render(libcamera::FrameBuffer *buffer, Image *image)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Indicate the widget paints all its pixels, to optimize rendering by
|
||||
* skipping erasing the widget before painting.
|
||||
*/
|
||||
setAttribute(Qt::WA_OpaquePaintEvent, true);
|
||||
update();
|
||||
|
||||
if (buffer)
|
||||
|
@ -129,6 +138,11 @@ void ViewFinderQt::stop()
|
|||
buffer_ = nullptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* The logo has a transparent background, reenable erasing the widget
|
||||
* before painting.
|
||||
*/
|
||||
setAttribute(Qt::WA_OpaquePaintEvent, false);
|
||||
update();
|
||||
}
|
||||
|
||||
|
@ -143,8 +157,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);
|
||||
}
|
||||
|
||||
painter.drawImage(place_, image_, image_.rect());
|
||||
return;
|
||||
}
|
||||
|
@ -170,7 +198,6 @@ void ViewFinderQt::paintEvent(QPaintEvent *)
|
|||
else
|
||||
point.setY((height() - pixmap_.height()) / 2);
|
||||
|
||||
painter.setBackgroundMode(Qt::OpaqueMode);
|
||||
painter.drawPixmap(point, pixmap_);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue