gpt4 book ai didi

c++ - 带有像素图图像的 QLabel 变得模糊

转载 作者:行者123 更新时间:2023-11-30 03:47:51 28 4
gpt4 key购买 nike

我有一张图片需要显示为 QLabel 的背景。这是我的代码(摘自 Qt 文档 here ):

#include <QtWidgets>    
#include "imageviewer.h"

ImageViewer::ImageViewer()
{
imageLabel = new QLabel;
imageLabel->setBackgroundRole(QPalette::Base);
imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
imageLabel->setScaledContents(true);
setCentralWidget(imageLabel);

createActions();
createMenus();

resize(570,357);
}


bool ImageViewer::loadFile(const QString &fileName)
{
QImageReader reader(fileName);
const QImage image = reader.read();
if (image.isNull()) {
QMessageBox::information(this, QGuiApplication::applicationDisplayName(),
tr("Cannot load %1.").arg(QDir::toNativeSeparators(fileName)));
setWindowFilePath(QString());
imageLabel->setPixmap(QPixmap());
imageLabel->adjustSize();
return false;
}
imageLabel->setPixmap(QPixmap::fromImage(image).scaled(size(),Qt::KeepAspectRatio,Qt::SmoothTransformation));
return true;
}



void ImageViewer::open()
{
QStringList mimeTypeFilters;
foreach (const QByteArray &mimeTypeName, QImageReader::supportedMimeTypes())
mimeTypeFilters.append(mimeTypeName);
mimeTypeFilters.sort();
const QStringList picturesLocations = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation);
QFileDialog dialog(this, tr("Open File"),
picturesLocations.isEmpty() ? QDir::currentPath() : picturesLocations.last());
dialog.setAcceptMode(QFileDialog::AcceptOpen);
dialog.setMimeTypeFilters(mimeTypeFilters);
dialog.selectMimeTypeFilter("image/jpeg");

while (dialog.exec() == QDialog::Accepted && !loadFile(dialog.selectedFiles().first())) {}
}

void ImageViewer::createActions()
{
openAct = new QAction(tr("&Open..."), this);
openAct->setShortcut(tr("Ctrl+O"));
connect(openAct, SIGNAL(triggered()), this, SLOT(open()));

}

void ImageViewer::createMenus()
{
fileMenu = new QMenu(tr("&File"), this);
fileMenu->addAction(openAct);

menuBar()->addMenu(fileMenu);

}

头文件:

#ifndef IMAGEVIEWER_H
#define IMAGEVIEWER_H

#include <QMainWindow>

class QAction;
class QLabel;
class QMenu;
class QScrollArea;
class QScrollBar;

class ImageViewer : public QMainWindow
{
Q_OBJECT

public:
ImageViewer();
bool loadFile(const QString &);

private slots:
void open();

private:
void createActions();
void createMenus();

QLabel *imageLabel;
QAction *openAct;
QMenu *fileMenu;
};

#endif

主要内容:

#include <QApplication>
#include <QCommandLineParser>

#include "imageviewer.h"

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QGuiApplication::setApplicationDisplayName(ImageViewer::tr("Image Viewer"));
ImageViewer imageViewer;
imageViewer.show();
return app.exec();
}

如您所见,视口(viewport)大小为 570 x 357。我使用的图像是 this (尺寸是2560*1600,长宽比都差不多1.6,这里上传太大,截图上传):

enter image description here

但是当我打开应用程序并在其中添加图像时,我在 QLabel 中获得的图像非常模糊:

enter image description here

如何使标签中的图像定义为实际图像(它是 bmp 格式,因此您必须在 Mac 的文件打开对话框中将 mime 类型更改为 bmp )?

当我通过 QPainter 执行此任务时,即从图像文件中制作一个 QImage,然后将其传递给画家并调用 update 结果很好。但我需要能够在单击时内联缩放图像(我通过调用 QLabel 上的 resize() 来实现),以及 QPainter 方式不允许我缩放图像。

平台 - OS X 10.10(视网膜显示屏)、Qt 5.3.1、32 位。

最佳答案

您在 Qt 5.3 中的 Retina 显示屏 Mac 上遇到了 QLabel 中的一个已知错误: https://bugreports.qt.io/browse/QTBUG-42503

从你的图像来看,当你使用 QLabel 时,你似乎只是获得了图像的非视网膜版本,但如果你在 QPainter 中手动编码,你将获得源 QImage 的完整分辨率。如果是这样,那确实是这个bug导致的。

您有两个解决方案:

  1. 推出您自己的解决方案,不要使用 QLabel。没有理由不使用 QLabel 就不能轻松地“内联缩放图像”(只需使用自定义 QWidget 类和重写的 PaintEvent)。

  2. 升级到此错误已修复的 Qt 版本。无论如何,这可能是正确的解决方案,除非最新版本中有任何回归导致您的应用程序出现问题。根据错误报告,此问题已在 v5.5.0 中修复,因此最新的 v5.5.1 应该可以正常工作。

第一种方法的示例(为简洁起见,我将 header 留在 header 文件中,它非常简单):

void ImageWidget::setImage(QImage image)
{
//Set the image and invalidate our cached pixmap
m_image = image;
m_cachedPixmap = QPixmap();
update();
}

void ImageWidget::paintEvent(QPaintEvent *)
{
if ( !m_image.isNull() )
{
QSize scaledSize = size() * devicePixelRatio();
if (m_cachedPixmap.size() != scaledSize)
{
QImage scaledImage = m_image.scaled(scaledSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
m_cachedPixmap = QPixmap::fromImage(scaledImage);
m_cachedPixmap.setDevicePixelRatio(devicePixelRatio());
}

QPainter p(this);
p.drawPixmap(0, 0, m_cachedPixmap);
}
}

这只是一个非常基本的小部件,它只是将 QImage 绘制到其完整大小,尊重 DevicePixelRatio,从而利用 Retina 分辨率。注意:在非 Retina 机器上编码,所以我不能保证它在 Retina 上工作,但我从 QLabel 的 Qt 5.5.1 修复中获得了基本实现。与 QLabel 一样,它也缓存 Pixmap,因此它不必在每次调用 paintEvent 时都重新缩放,除非小部件实际上已调整大小。

关于c++ - 带有像素图图像的 QLabel 变得模糊,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33483624/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com