• QPixmap图像处理详解



    QPixmap 是Qt中用于处理图像的类,它是基于屏幕的图像表示方式,可以用于在Qt应用程序中显示图像、图标和背景。以下是关于 QPixmap的一些主要知识点:

    一、QPixmap 图像加载和保存

    1.1 QPixmap加载图像

    你可以使用 QPixmap构造函数或者 load() 函数来加载图像。构造函数可以直接传递图像文件的路径,load() 函数则需要在加载前设置文件路径

    QPixmap pixmap("path/to/image.png"); // 使用构造函数加载图像
    // 或者
    QPixmap pixmap;
    pixmap.load("path/to/image.png"); // 使用load()函数加载图像
    
    • 1
    • 2
    • 3
    • 4

    1.2 QPixmap保存图像

    你可以使用 save() 函数将 QPixmap 对象保存为图像文件。你需要指定保存的文件名以及图像格式(如 PNG、JPEG 等)。

    pixmap.save("output/path/image.png"); // 保存为PNG格式
    // 或者
    pixmap.save("output/path/image.jpg", "JPEG"); // 保存为JPEG格式
    
    • 1
    • 2
    • 3

    1.3 QPixmap 图像加载和保存的实例

    以下是一个简单的实例,演示了如何使用 QPixmap 加载图像并将其保存为不同的格式。

    #include 
    #include 
    
    int main() {
        // 加载图像
        QPixmap pixmap("path/to/image.png");
        
        // 检查图像是否成功加载
        if (pixmap.isNull()) {
            qDebug() << "Failed to load image.";
            return 1;
        }
    
        // 保存图像为不同格式
        if (pixmap.save("path/to/output.png")) {
            qDebug() << "Image saved as PNG.";
        } else {
            qDebug() << "Failed to save image as PNG.";
        }
    
        if (pixmap.save("path/to/output.jpg", "JPEG")) {
            qDebug() << "Image saved as JPEG.";
        } else {
            qDebug() << "Failed to save image as JPEG.";
        }
    
        if (pixmap.save("path/to/output.bmp", "BMP")) {
            qDebug() << "Image saved as BMP.";
        } else {
            qDebug() << "Failed to save image as BMP.";
        }
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    在这个例子中,首先加载了一个图像文件(假设路径为 “path/to/image.png”),然后将其保存为不同格式的文件。请替换实际的文件路径和保存目标文件的格式。

    二、QPixmap绘制图像

    2.1 在窗口上绘制

    你可以使用 QPainter 类将 QPixmap 对象绘制到窗口、控件等上。QPainter 提供了丰富的绘制函数,可以用于绘制线条、矩形、圆形等,也可以用于绘制图像。

    QPainter painter(this); // 在窗口上绘制
    painter.drawPixmap(10, 10, pixmap); // 在坐标(10, 10)处绘制图像
    
    • 1
    • 2

    2.2 QPixmap缩放绘制

    你可以使用 scaled() 函数对 QPixmap 进行缩放,然后将缩放后的图像绘制到窗口上。

    QPixmap scaledPixmap = pixmap.scaled(50, 50); // 缩放为50x50大小
    painter.drawPixmap(10, 10, scaledPixmap); // 在坐标(10, 10)处绘制缩放后的图像
    
    • 1
    • 2

    2.3 QPixmap旋转绘制

    你可以使用 QTransform 类对 QPixmap 进行旋转,然后将旋转后的图像绘制到窗口上。

    QTransform transform;
    transform.rotate(90); // 旋转90度
    QPixmap rotatedPixmap = pixmap.transformed(transform);
    painter.drawPixmap(10, 10, rotatedPixmap); // 在坐标(10, 10)处绘制旋转后的图像
    
    • 1
    • 2
    • 3
    • 4

    2.4 QPixmap 绘制图像的实例

    以下是一个简单的实例,演示了如何使用 QPixmap 在窗口上绘制图像,并且进行缩放和旋转操作。

    #include 
    #include 
    #include 
    #include 
    
    class MyWidget : public QMainWindow {
    public:
        void paintEvent(QPaintEvent *) override {
            QPixmap pixmap("path/to/image.png");
    
            QPainter painter(this);
            painter.drawPixmap(10, 10, pixmap); // 在坐标(10, 10)处绘制原始图像
    
            QPixmap scaledPixmap = pixmap.scaled(50, 50); // 缩放为50x50大小
            painter.drawPixmap(70, 10, scaledPixmap); // 在坐标(70, 10)处绘制缩放后的图像
    
            QTransform transform;
            transform.rotate(90); // 旋转90度
            QPixmap rotatedPixmap = pixmap.transformed(transform);
            painter.drawPixmap(130, 10, rotatedPixmap); // 在坐标(130, 10)处绘制旋转后的图像
        }
    };
    
    int main(int argc, char *argv[]) {
        QApplication app(argc, argv);
        MyWidget widget;
        widget.show();
        return app.exec();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    在这个例子中,MyWidget 是一个继承自 QMainWindow 的自定义窗口类。在 paintEvent 函数中,首先加载了一个图像文件(假设路径为 “path/to/image.png”),然后在窗口的不同位置绘制了原始图像、缩放后的图像和旋转后的图像。请替换实际的文件路径。

    三、图像转换

    你可以使用 QPixmap::toImage()QPixmap 转换为 QImage 对象,从而在QImage的基础上进行图像处理操作。

    3.1 QImage转QPixmap

    你可以使用 QPixmap 的构造函数将 QImage 对象转换为 QPixmap。

    QImage image("path/to/image.png");
    QPixmap pixmap = QPixmap::fromImage(image);
    
    • 1
    • 2

    3.2 QPixmap转QImage

    你可以使用 toImage() 函数将 QPixmap 转换为 QImage。

    QImage image = pixmap.toImage();
    
    
    • 1
    • 2
    • QPixmap 图像转换的实例
      以下是一个简单的实例,演示了如何使用 QPixmap 进行图像转换,包括从 QImage 转换为 QPixmap,以及从文件加载并转换为 QImageQPixmap
    #include 
    #include 
    #include 
    
    int main() {
        // 从文件加载图像并转换为 QPixmap
        QPixmap pixmap("path/to/image.png");
        
        // 从 QImage 转换为 QPixmap
        QImage image("path/to/image.png");
        QPixmap convertedPixmap = QPixmap::fromImage(image);
        
        // 从 QPixmap 转换为 QImage
        QImage convertedImage = pixmap.toImage();
    
        // 检查转换是否成功
        if (!pixmap.isNull() && !convertedPixmap.isNull() && !convertedImage.isNull()) {
            qDebug() << "Image conversion successful.";
        } else {
            qDebug() << "Image conversion failed.";
            return 1;
        }
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    在这个例子中,首先从文件加载了一个图像(假设路径为 “path/to/image.png”),然后将其转换为 QPixmap 对象。接着,将该图像转换为 QImage,再将 QPixmap 转换为 QImage。在转换过程中,使用了相关的转换函数。请替换实际的文件路径。

    3.3 像素级别操作

    你可以使用 setPixel()pixel() 函数来直接操作 QPixmap 中的像素。

    3.4 绘制图标

    在Qt中,QPixmap 类提供了丰富的绘图功能,包括绘制图标、图形、文本等。下面是关于如何使用 QPixmap 绘制图标的详细说明和示例。

    绘制图标的函数:

    1. QPixmap::drawPixmap()
      这个函数可以将一个 QPixmap 绘制到另一个 QPixmap 上,也可以绘制到 QPainter 对象上。它的参数包括目标绘图对象、目标位置、源绘图对象、源位置和大小。

      void QPixmap::drawPixmap(int x, int y, const QPixmap & pixmap, int sx, int sy, int sw, int sh);
      
      • 1

    示例代码:

    下面是一个示例,演示如何使用 QPixmap 绘制图标,并显示在窗口中:

    #include 
    #include 
    #include 
    #include 
    
    int main(int argc, char *argv[]) {
        QApplication app(argc, argv);
    
        // 创建一个空的QPixmap作为绘制目标
        QPixmap pixmap(100, 100);
        pixmap.fill(Qt::white); // 填充白色背景
    
        // 在pixmap上绘制图标
        QPainter painter(&pixmap);
        painter.setRenderHint(QPainter::Antialiasing); // 反锯齿
        painter.setRenderHint(QPainter::SmoothPixmapTransform); // 平滑变换
    
        // 绘制一个蓝色的圆形图标
        painter.setBrush(Qt::blue);
        painter.drawEllipse(10, 10, 80, 80);
    
        // 将绘制好的图标显示在窗口中
        QLabel label;
        label.setPixmap(pixmap);
        label.show();
    
        return app.exec();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    在这个示例中,我们创建了一个100x100的空 QPixmap,并使用 QPainter 绘制了一个蓝色的圆形图标。最后,将绘制好的图标显示在一个窗口中。你可以根据需要调整图标的大小、形状和颜色。

    3.5 缓存图像

    QPixmap 可以用作缓存图像,以提高渲染性能。通常,在绘制大量图形元素或者需要频繁重绘的场景下,使用 QPixmap 缓存已经绘制的图像,可以避免不必要的重绘操作,提高应用程序的渲染性能。

    以下是一个简单的示例,演示了如何使用 QPixmap 进行缓存,以减少渲染开销。在这个示例中,我们绘制了一个简单的图形,然后将它缓存到 QPixmap 中,之后只需绘制 QPixmap,而不是重新绘制图形,从而提高了性能。

    #include 
    #include 
    #include 
    #include 
    #include 
    
    class CustomWidget : public QWidget {
    public:
        CustomWidget(QWidget *parent = nullptr) : QWidget(parent) {
            // 创建一个空的QPixmap对象
            cachedPixmap = QPixmap(size());
            cachedPixmap.fill(Qt::white);  // 用白色填充
    
            // 使用定时器触发重绘
            QTimer *timer = new QTimer(this);
            connect(timer, &QTimer::timeout, this, QOverload<>::of(&QWidget::update));
            timer->start(1000);  // 每秒触发一次重绘
        }
    
    protected:
        void paintEvent(QPaintEvent *event) override {
            QPainter painter(this);
            // 使用缓存的QPixmap进行绘制
            painter.drawPixmap(0, 0, cachedPixmap);
    
            // 绘制一个矩形(模拟复杂的图形绘制)
            QPainter pixmapPainter(&cachedPixmap);
            pixmapPainter.fillRect(50, 50, 100, 100, Qt::blue);  // 绘制蓝色矩形
        }
    
    private:
        QPixmap cachedPixmap;
    };
    
    int main(int argc, char *argv[]) {
        QApplication app(argc, argv);
    
        CustomWidget widget;
        widget.setWindowTitle("Pixmap Caching Example");
        widget.resize(300, 300);
        widget.show();
    
        return app.exec();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    在这个示例中,CustomWidget 类继承自 QWidget,并且在构造函数中创建了一个空的 QPixmap 对象 cachedPixmap,然后使用定时器触发每秒的重绘。在 paintEvent 函数中,使用 QPainter 绘制缓存的 QPixmap,并在缓存的 QPixmap 上绘制了一个蓝色矩形。因为定时器每秒触发一次重绘,但实际上只有矩形的部分需要重新绘制,所以使用了 QPixmap 缓存,避免了不必要的图形绘制操作,提高了性能。

    这个示例演示了如何使用 QPixmap 缓存图像,从而在需要频繁绘制的情况下提高应用程序的渲染性能。

    四、QImage和QPixmap的区别

    1. 数据结构和用途

    • QImage: QImage 是一个更底层的图像类,它包含了图像的像素数据、颜色信息、以及图像的格式等。QImage 可以用于图像处理、像素级别的操作、格式转换等。QImage 是一个灵活的图像处理类,可以直接从文件、内存、设备等加载图像数据。

    • QPixmap: QPixmap 是一个基于设备的图像表示,它通常用于在界面上显示图像、图标、背景等。QPixmap 隐藏了图像的底层数据结构,提供了方便的界面显示接口。QPixmap 可以用于在窗口、控件等上绘制图像,以及进行界面元素的图像显示。

    2. 适用场景

    • QImage: 适用于需要对图像进行复杂处理、像素级别的操作、格式转换等情况。如果你需要在图像上进行算法操作、图像分析、修改像素值等,通常使用 QImage 更为合适。

    • QPixmap: 适用于在界面上显示图像、图标、背景等情况。如果你需要在界面元素(例如窗口、按钮、标签等)上显示图像,通常使用 QPixmap 更为方便。QPixmap 是更高级、更用户友好的图像显示类。

    3.性能和优化

    • QImage: 由于包含了详细的图像数据,QImage 的内存占用较大。在处理大量图像数据时,可能会占用较多的内存。同时,QImage 的像素级别操作可能较为耗时,特别是在大尺寸图像上。

    • QPixmap: QPixmap 是一个较为轻量级的图像表示,它通常会被优化以适应界面的显示需求。在绘制图像到界面上时,QPixmap 的性能较好,因为它通常会利用硬件加速等技术来提高绘制效率。

    综上所述,如果你需要进行复杂的图像处理和操作,或者需要进行像素级别的操作,应该选择 QImage。如果你只需要在界面上显示图像或图标,或者需要进行界面元素的绘制,那么 QPixmap 更为适合。

  • 相关阅读:
    iOS APP 转让避坑指南
    操作系统备考学习 day3 (2.1.1 - 2.1.6)
    北京君正应用案例:联想新款Yoga Book 9i亮相 CES
    大数据杂谈
    数据库高级 I
    微服务组件之Zuul
    HOOPS 3DGS技术概述
    路径问题【动态规划】
    好家伙,分布式配置中心这种组件真的是神器
    git修改默认分支
  • 原文地址:https://blog.csdn.net/arv002/article/details/133845597