Qt 绘制图片自适应窗口大小(QImage,QPixmap,QLabel)

工作过程中需要用某个控件展示本地图片文件,但又不想图片比例发生变化,导致文件查看时有变形感。因为只是极小一部分内容就直接使用QLable控件来完成此功能。

下面简单介绍一下我个人使用Label展示图片常用方法,若有错误欢迎指正

填充整个控件

ui->imgLable->setPixmap(QPixmap(imgpath));//label 加载图片imgpath
ui->imgLable->setScaledContents(true);    //根据label大小缩放图片
效果:图片填充整个label,且可以随label变化而变化,缺点则会改变图片比例导致有些图片显示不正常
// 根据label宽度等比例缩放图片
ui->imgLable->setPixmap(pix.scaledToWidth(ui->imgLable->width()));

// 根据label高度等比例缩放图片
ui->imgLable->setPixmap(pix.scaledToHeight(ui->imgLable->height()));
效果:图片根据指定高度或宽度进行等比例变换,缺点是当label控件为preferred将会导致窗口忽大忽小,友好度较差;

等比例填充

QPixmap pix(imgpath);
int scalHeight = ui->imgLable->height();
int scalWidth = pix.scaledToHeight(scalHeight).width();//根据label高度计算得到控件目标宽度

if(ui->imgLable->width() < scalWidth)
{//再次调整,确保图片能够在控件中完整显示
    scalWidth = ui->imgLable->width();
    scalHeight = pix.scaledToWidth(scalWidth).height();
}

ui->imgLable->setPixmap(pix.scaled(scalWidth,scalHeight,Qt::KeepAspectRatio));

效果:此时图片比例不发生变化,且不会出现忽大忽小的现象。缺点是当主窗口改变大小时label图片大小不随之变化,需要主动做刷新操作;

以上操作还有更简单办法:
    pix = pix.scaled(ui->imgLable->width(),ui->imgLable->height(),Qt::KeepAspectRatio);
    ui->imgLable->setPixmap(pix);
注意scale参数AspectRatioMode,此参数用于控制缩放时是否保留原有比例关系:
enum AspectRatioMode {
        IgnoreAspectRatio,
        KeepAspectRatio,
        KeepAspectRatioByExpanding
    };
查看Qt帮助文档:

计算显示窗大小

int size_w = FIX_WIDTH;//展示框宽
int size_h = FIX_HEIGHT;//展示框高

QPixmap pix(imagefile);
int width = pix.width();
int height = pix.height();

int scaleWidth = size_w;//最终计算图片宽度
int scalHeight = size_h;//最终计算图片高度

if(width > size_w)//图片本身宽度大于展示框宽度,等比例缩放
{
    scaleWidth = size_w;
    scalHeight = scaleWidth *height /width;
    qDebug() << scalHeight << scaleWidth;
    if(scalHeight > size_h)
    {//缩放后高度大于展示框,根据展示框高度等比例缩放
        scalHeight = size_h;
        scaleWidth = scalHeight * width/height;
    }
}
else if(height > size_h)//图片本身高度大于展示框,等比例缩放
{
    scalHeight = size_h;
    scaleWidth = scalHeight * size_w/height;

    qDebug() << scalHeight << scaleWidth;
    if(scaleWidth > size_w)
    {
        scaleWidth = size_w;
        scalHeight = scaleWidth *height /width;
    }
}
else 
{
    //符合展示框高度和宽度,可以直接使用
}

QSS风格设置

最近又重新看了下图片缩放这个问题,其实直接通过Qss风格设置可以直接完成窗体图片显示,

打开帮助文档查询索引:Customizing Qt Widgets Using Style SheetsQt Style Sheets Reference有相关窗体qss设置详细解释,以下为图片展示部分内容

border-image

图片填充整个boder区域,当图片和窗口大小不一致时主动缩放图片,此时图片原本比例不再考虑;

                                           图 border-image加载图片

background-image

原图不根据窗口大小进行缩放,不足显示区域则主动平铺记载图片

 

                                             图 background-image加载图片

image

图片填充窗体content区域,且图片只会根据窗口大小进行等比例缩小不会等比例放大。可以和image-position配合使用指定图片展示位置,如:

image-position:center top   图片显示水平方向:中间,垂直方向:靠上;

                                                   图 image加载图片