1.QImage scaledToWidth(int w, Qt::TransformationMode mode = Qt::FastTransformation) const;
/*!
\fn QImage QImage::scaledToWidth(int width, Qt::TransformationMode mode) const
Returns a scaled copy of the image. The returned image is scaled
to the given \a width using the specified transformation \a
mode.
This function automatically calculates the height of the image so
that its aspect ratio is preserved.
If the given \a width is 0 or negative, a null image is returned.
\sa {QImage#Image Transformations}{Image Transformations}
*/
QImage QImage::scaledToWidth(int w, Qt::TransformationMode mode) const
{
if (!d) {
qWarning("QImage::scaleWidth: Image is a null image");
return QImage();
}
if (w <= 0)
return QImage();
Q_TRACE_SCOPE(QImage_scaledToWidth, w, mode);
qreal factor = (qreal) w / width();
QTransform wm = QTransform::fromScale(factor, factor);
return transformed(wm, mode);
}
QTransform QTransform::fromScale(qreal sx, qreal sy)
{
#ifndef QT_NO_DEBUG
if (qIsNaN(sx) | qIsNaN(sy)) {
nanWarning("fromScale");
return QTransform();
}
#endif
QTransform transform(sx, 0, 0, 0, sy, 0, 0, 0, 1);
if (sx == 1. && sy == 1.)
transform.m_type = TxNone;
else
transform.m_type = TxScale;
transform.m_dirty = TxNone;
return transform;
}
QTransform(qreal h11, qreal h12, qreal h13,
qreal h21, qreal h22, qreal h23,
qreal h31, qreal h32, qreal h33)
: m_matrix{ {h11, h12, h13}, {h21, h22, h23}, {h31, h32, h33} }
, m_type(TxNone)
, m_dirty(TxProject) {}
QImage QImage::transformed(const QTransform &matrix, Qt::TransformationMode mode ) const
{
if (!d)
return QImage();
Q_TRACE_SCOPE(QImage_transformed, matrix, mode);
// source image data
const int ws = width();
const int hs = height();
// target image data
int wd;
int hd;
// compute size of target image
QTransform mat = trueMatrix(matrix, ws, hs);
bool complex_xform = false;
bool scale_xform = false;
bool nonpaintable_scale_xform = false;
if (mat.type() <= QTransform::TxScale) {
if (mat.type() == QTransform::TxNone) // identity matrix
return *this;
else if (mat.m11() == -1. && mat.m22() == -1.)
return rotated180(*this);
if (mode == Qt::FastTransformation) {
hd = qRound(qAbs(mat.m22()) * hs);
wd = qRound(qAbs(mat.m11()) * ws);
} else {
hd = int(qAbs(mat.m22()) * hs + 0.9999);
wd = int(qAbs(mat.m11()) * ws + 0.9999);
}
scale_xform = true;
// The paint-based scaling is only bilinear, and has problems
// with scaling smoothly more than 2x down.
if (hd * 2 < hs || wd * 2 < ws)
nonpaintable_scale_xform = true;
} else {
if (mat.type() <= QTransform::TxRotate && mat.m11() == 0 && mat.m22() == 0) {
if (mat.m12() == 1. && mat.m21() == -1.)
return rotated90(*this);
else if (mat.m12() == -1. && mat.m21() == 1.)
return rotated270(*this);
}
QPolygonF a(QRectF(0, 0, ws, hs));
a = mat.map(a);
QRect r = a.boundingRect().toAlignedRect();
wd = r.width();
hd = r.height();
complex_xform = true;
}
if (wd == 0 || hd == 0)
return QImage();
if (scale_xform && mode == Qt::SmoothTransformation) {
switch (format()) {
case QImage::Format_RGB32:
case QImage::Format_ARGB32_Premultiplied:
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
case QImage::Format_RGBX8888:
#endif
case QImage::Format_RGBA8888_Premultiplied:
#if QT_CONFIG(raster_64bit)
case QImage::Format_RGBX64:
case QImage::Format_RGBA64_Premultiplied:
#endif
// Use smoothScaled for scaling when we can do so without conversion.
if (mat.m11() > 0.0F && mat.m22() > 0.0F)
return smoothScaled(wd, hd);
break;
default:
break;
}
// Otherwise only use it when the scaling factor demands it, or the image is large enough to scale multi-threaded
if (nonpaintable_scale_xform
#if QT_CONFIG(thread) && !defined(Q_OS_WASM)
|| (ws * hs) >= (1<<20)
#endif
) {
if (mat.m11() < 0.0F && mat.m22() < 0.0F) { // horizontal/vertical flip
return smoothScaled(wd, hd).mirrored(true, true).convertToFormat(format());
} else if (mat.m11() < 0.0F) { // horizontal flip
return smoothScaled(wd, hd).mirrored(true, false).convertToFormat(format());
} else if (mat.m22() < 0.0F) { // vertical flip
return smoothScaled(wd, hd).mirrored(false, true).convertToFormat(format());
} else { // no flipping
return smoothScaled(wd, hd).convertToFormat(format());
}
}
}
int bpp = depth();
qsizetype sbpl = bytesPerLine();
const uchar *sptr = bits();
QImage::Format target_format = d->format;
if (complex_xform || mode == Qt::SmoothTransformation) {
if (d->format < QImage::Format_RGB32 || (!hasAlphaChannel() && complex_xform)) {
target_format = qt_alphaVersion(d->format);
}
}
QImage dImage(wd, hd, target_format);
QIMAGE_SANITYCHECK_MEMORY(dImage);
if (target_format == QImage::Format_MonoLSB
|| target_format == QImage::Format_Mono
|| target_format == QImage::Format_Indexed8) {
dImage.d->colortable = d->colortable;
dImage.d->has_alpha_clut = d->has_alpha_clut | complex_xform;
}
// initizialize the data
if (target_format == QImage::Format_Indexed8) {
if (dImage.d->colortable.size() < 256) {
// colors are left in the color table, so pick that one as transparent
dImage.d->colortable.append(0x0);
memset(dImage.bits(), dImage.d->colortable.size() - 1, dImage.d->nbytes);
} else {
memset(dImage.bits(), 0, dImage.d->nbytes);
}
} else
memset(dImage.bits(), 0x00, dImage.d->nbytes);
if (target_format >= QImage::Format_RGB32) {
// Prevent QPainter from applying devicePixelRatio corrections
const QImage sImage = (devicePixelRatio() != 1) ? QImage(constBits(), width(), height(), format()) : *this;
Q_ASSERT(sImage.devicePixelRatio() == 1);
Q_ASSERT(sImage.devicePixelRatio() == dImage.devicePixelRatio());
QPainter p(&dImage);
if (mode == Qt::SmoothTransformation) {
p.setRenderHint(QPainter::Antialiasing);
p.setRenderHint(QPainter::SmoothPixmapTransform);
}
p.setTransform(mat);
p.drawImage(QPoint(0, 0), sImage);
} else {
bool invertible;
mat = mat.inverted(&invertible); // invert matrix
if (!invertible) // error, return null image
return QImage();
// create target image (some of the code is from QImage::copy())
int type = format() == Format_Mono ? QT_XFORM_TYPE_MSBFIRST : QT_XFORM_TYPE_LSBFIRST;
qsizetype dbpl = dImage.bytesPerLine();
qt_xForm_helper(mat, 0, type, bpp, dImage.bits(), dbpl, 0, hd, sptr, sbpl, ws, hs);
}
copyMetadata(dImage.d, d);
return dImage;
}
根据输入的w参数,计算缩放因子factor。
把facotor作为参数,调用QTransform::fromScale, 该函数返回一个QTransform对象。
在QTransform的构造函数里,创建了一个矩阵,用于保存缩放参数。
之后,调用transformed函数进行转换。
2.QImage scaledToHeight(int h, Qt::TransformationMode mode = Qt::FastTransformation) const;
/*!
\fn QImage QImage::scaledToHeight(int height, Qt::TransformationMode mode) const
Returns a scaled copy of the image. The returned image is scaled
to the given \a height using the specified transformation \a
mode.
This function automatically calculates the width of the image so that
the ratio of the image is preserved.
If the given \a height is 0 or negative, a null image is returned.
\sa {QImage#Image Transformations}{Image Transformations}
*/
QImage QImage::scaledToHeight(int h, Qt::TransformationMode mode) const
{
if (!d) {
qWarning("QImage::scaleHeight: Image is a null image");
return QImage();
}
if (h <= 0)
return QImage();
Q_TRACE_SCOPE(QImage_scaledToHeight, h, mode);
qreal factor = (qreal) h / height();
QTransform wm = QTransform::fromScale(factor, factor);
return transformed(wm, mode);
}