使用 QPainter::scale(x,y) 时如何保持 QPainter::drawPixmap 中的 QPixamp 质量?

问题描述 投票:0回答:1

我正在使用QWidget及其paintEvent。 我使用 QPainter::scale(zoom,zoom) 来缩放小部件上的背景图像。 然后我想绘制一些前景图标并始终保持它们的大小相同,同时保持质量。

问题是,即使 QPixamp 保持相同的尺寸,其质量也会下降。 “变焦”越大,质量损失就越大。

最小代码示例:

void myPainter::paintEvent(QPaintEvent *)
{
 QPainter p(this);
 p.scale(myZoom,myZoom)
 .
 .
 .
 double tagSize = t->icon_->height() / zoom;
 QPoint tagpoint = rect().center();
 p.drawPixmap(tagpoint, t->icon_->scaledToHeight(tagSize,Qt::SmoothTransformation));
}

我使用了带有缩放QPixmap的drawPixamp。 我预计 QPixamp 的质量不会下降,而是保持不变。

编辑:(部分解决方案) 为了保持像素图质量,可以 取消缩放、绘制、缩放以保持良好的图像质量和图像相同大小而不调整大小。

p.scale(1/zoom,1/zoom);
p.drawPixmap(tagpoint * zoom, *t->icon_);
p.scale(zoom,zoom);

这迫使标签点进行新的计算以保持位置相同,但在计算位置并考虑缩放后似乎可以工作。

qt qwidget qpainter qpixmap
1个回答
0
投票

质量“降低”,因为您缩小了像素图。

这就像将 100x100 图像缩放到 50x50,然后按 2 倍比例缩放:退化是显而易见的,因为缩放图像会丢失原始内容,尤其是在缩小时。

请记住,像素图是像素图(像素图)。每次缩放都可能会导致内容丢失,除非使用 2 的幂因子进行缩放并且不应用缩放过滤器。 考虑这个规范的源图像,分辨率为 512x512:

Standard test image, original 然后将其缩小一半大小:

Scaled down image 然后这就是使用“放大”系数 2 绘制的方式:

Zoomed in image 这是因为应用于画家的变换只能使用它提供的数据:在这种特定情况下,是缩小图像的“缩小”像素图。您无法获得“未降级”图像,因为该数据

存在于缩放后的像素图中。 在不损失质量的情况下获得适当结果的唯一安全方法是不是通过缩放图像,而是始终使用适当的变换来绘制源。

您可以按照问题中的建议进行操作,或者最终使用 QPainter 状态进行操作。 p.save(); p.resetTransform(); // or, alternatively, p.scale(1/zoom, 1/zoom) as above p.drawPixmap(tagpoint * zoom, *t->icon_); p.restore();

结果将与您的建议相同。

请注意,保存画家状态可能比“unscale+paint+rescale”效率稍低(因为它保存了其完整状态,包括当前的笔、画笔等,这在这种特定情况下显然是不必要的),但是在某些情况下它更有效,因为拥有 QPainter 状态的
stacks

可以简化代码编写/可读性/调试。

© www.soinside.com 2019 - 2024. All rights reserved.