问题
Hey so I have this function which works and scales the image nicely and will shrink and expand it given the correct shortcuts from the UI.
However I am losing picture quality when I zoom back to the original scaled factor of the image. I have tried making 'orig' which is a global 'const QPixmap*'. 'orig' is defined when the image is loaded into the UI. I then set 'pixmap = orig' (seen below in the code) but this doesn't seem to work, and I'm not sure why.
The idea is to make a copy of it without rewriting the original's pixmap, to preserve the pixel quality, and then to reload the original pixmap whenever the function gets called.
void FragTreeViewer::scaleImage(double factor)
{
Q_ASSERT(imageLabel->pixmap());
const QPixmap* pixmap = orig;
scaleFactor *= factor;
int w = (imageLabel->width())*scaleFactor;
int h = (imageLabel->height())*scaleFactor;
imageLabel->setPixmap(pixmap->scaled(w, h, Qt::KeepAspectRatio));
adjustScrollBar(scrollArea->horizontalScrollBar(), scaleFactor);
adjustScrollBar(scrollArea->verticalScrollBar(), scaleFactor);
//zoomInAct->setEnabled(scaleFactor < 3.0);
//zoomOutAct->setEnabled(scaleFactor > 0.333);
}
回答1:
You're not showing the relevant code, what you do show is fine. From what I can glean you're trying to resize both the pixmap shown in the label, and the label itself. You should be doing one or the other, not both. It's simplest to resize the label, and let the scroll area work its magic. This makes the whole affair trivial.
The code below, sans modifications needed to fix it, is what you should have posted in your question.
// https://github.com/KubaO/stackoverflown/tree/master/questions/image-view-scale-31619246
#include <QtWidgets>
#include <QtNetwork>
class FragTreeViewer : public QWidget {
QGridLayout m_layout{this};
QScrollArea m_area;
QLabel m_imageLabel, m_scaleLabel;
QPushButton m_zoomOut{"Zoom Out"}, m_zoomIn{"Zoom In"};
double m_scaleFactor = 1.0;
public:
void setImage(const QImage & img) {
m_scaleFactor = 1.0;
m_imageLabel.setPixmap(QPixmap::fromImage(img));
scaleImage(1.0);
}
FragTreeViewer() {
m_layout.addWidget(&m_area, 0, 0, 1, 3);
m_layout.addWidget(&m_zoomOut, 1, 0);
m_layout.addWidget(&m_scaleLabel, 1, 1);
m_layout.addWidget(&m_zoomIn, 1, 2);
m_area.setWidget(&m_imageLabel);
m_imageLabel.setScaledContents(true);
connect(&m_zoomIn, &QPushButton::clicked, [this]{ scaleImage(1.1); });
connect(&m_zoomOut, &QPushButton::clicked, [this]{ scaleImage(1.0/1.1); });
}
void scaleImage(double factor) {
m_scaleFactor *= factor;
m_scaleLabel.setText(QStringLiteral("%1%").arg(m_scaleFactor*100, 0, 'f', 1));
QSize size = m_imageLabel.pixmap()->size() * m_scaleFactor;
m_imageLabel.resize(size);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
FragTreeViewer viewer;
QNetworkAccessManager mgr;
QScopedPointer<QNetworkReply> rsp(
mgr.get(QNetworkRequest({"http://i.imgur.com/ikwUmUV.jpg"})));
QObject::connect(rsp.data(), &QNetworkReply::finished, [&]{
if (rsp->error() == QNetworkReply::NoError)
viewer.setImage(QImage::fromData(rsp->readAll()));
});
viewer.show();
return a.exec();
}
来源:https://stackoverflow.com/questions/31619246/qlabel-scaling-images-for-zooming-and-losing-picture-quality