QPixmap图像处理详解

文章目录

  • 一、QPixmap 图像加载和保存
    • 1.1 QPixmap加载图像
    • 1.2 QPixmap保存图像
    • 1.3 QPixmap 图像加载和保存的实例
  • 二、QPixmap绘制图像
    • 2.1 在窗口上绘制
    • 2.2 QPixmap缩放绘制
    • 2.3 QPixmap旋转绘制
    • 2.4 QPixmap 绘制图像的实例
    • 2.4 透明度和遮罩
  • 三、图像转换
    • 3.1 QImage转QPixmap
    • 3.2 QPixmap转QImage
    • 3.3 像素级别操作
    • 3.4 绘制图标
    • 3.5 缓存图像
  • 四、QImage和QPixmap的区别
    • 1. 数据结构和用途
    • 2. 适用场景
    • 3.性能和优化

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 QPixmap保存图像

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

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

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

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

#include <QPixmap>
#include <QDebug>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;
}

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

二、QPixmap绘制图像

2.1 在窗口上绘制

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

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

2.2 QPixmap缩放绘制

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

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

2.3 QPixmap旋转绘制

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

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

2.4 QPixmap 绘制图像的实例

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

#include <QApplication>
#include <QMainWindow>
#include <QPixmap>
#include <QPainter>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();
}

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

2.4 透明度和遮罩

在Qt中,QPixmap 类提供了处理图像的功能。你可以使用 QPixmap 实现图像的透明度和遮罩效果。

透明度设置:
透明度表示图像的不透明度程度,可以通过 setOpacity() 方法设置。透明度的值范围是从0.0(完全透明)到1.0(完全不透明)。

QPixmap pixmap("image.png");
pixmap.setOpacity(0.5); // 设置透明度为50%

遮罩设置:
遮罩是一张单色图像,用于指定原始图像的哪些部分是透明的。你可以使用 setMask() 方法将遮罩应用到 QPixmap 上。

QPixmap originalPixmap("image.png");
QPixmap maskPixmap("mask.png");
originalPixmap.setMask(maskPixmap.mask());

在这里,maskPixmap 是一个单色图像,它的白色部分表示原始图像可见的部分,黑色部分表示透明的部分。setMask() 方法会将遮罩应用到 originalPixmap 上,使得只有遮罩中白色部分的区域会显示,其他部分将变为透明。

示例代码:

以下是一个简单的实例,演示如何使用 QPixmap 设置图像透明度和遮罩效果:

#include <QApplication>
#include <QLabel>int main(int argc, char *argv[]) {QApplication app(argc, argv);// 创建原始图像QPixmap originalPixmap("image.png");// 设置透明度为50%originalPixmap.setOpacity(0.5);// 创建遮罩图像QPixmap maskPixmap("mask.png");// 应用遮罩效果originalPixmap.setMask(maskPixmap.mask());// 显示图像QLabel label;label.setPixmap(originalPixmap);label.show();return app.exec();
}

在这个示例中,image.png 是原始图像,mask.png 是遮罩图像。程序会将原始图像的透明度设置为50%,并且应用遮罩效果,只有遮罩图像中白色部分的区域会显示。

三、图像转换

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

3.1 QImage转QPixmap

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

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

3.2 QPixmap转QImage

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

QImage image = pixmap.toImage();
  • QPixmap 图像转换的实例
    以下是一个简单的实例,演示了如何使用 QPixmap 进行图像转换,包括从 QImage 转换为 QPixmap,以及从文件加载并转换为 QImageQPixmap
#include <QImage>
#include <QPixmap>
#include <QDebug>int main() {// 从文件加载图像并转换为 QPixmapQPixmap pixmap("path/to/image.png");// 从 QImage 转换为 QPixmapQImage image("path/to/image.png");QPixmap convertedPixmap = QPixmap::fromImage(image);// 从 QPixmap 转换为 QImageQImage convertedImage = pixmap.toImage();// 检查转换是否成功if (!pixmap.isNull() && !convertedPixmap.isNull() && !convertedImage.isNull()) {qDebug() << "Image conversion successful.";} else {qDebug() << "Image conversion failed.";return 1;}return 0;
}

在这个例子中,首先从文件加载了一个图像(假设路径为 “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);
    

示例代码:

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

#include <QApplication>
#include <QPixmap>
#include <QLabel>
#include <QPainter>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();
}

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

3.5 缓存图像

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

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

#include <QApplication>
#include <QWidget>
#include <QPainter>
#include <QPixmap>
#include <QTimer>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();
}

在这个示例中,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 更为适合。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/110657.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vtk简单介绍、渲染流程、简单示例

一、vtk简单介绍 Vtk&#xff08;visualization toolkit&#xff09;是一个开源的免费软件系统&#xff0c;主要用于三维计算机图形学、图像处理和可视化。 二、vtk渲染流程 流程图如下&#xff1a; 1.vtkSource 数据源 各个类型的图像原始数据。 2.vtkFilter 数据过滤器 …

多继承vs查看类结构

多继承里面的虚函数 类A有两个虚函数&#xff0c;类B重写了其中一个&#xff0c;类C重写了两个&#xff1b; 类C里面可以重写所有继承到的虚函数&#xff08;类A、类B里面的虚函数&#xff09; class A { public:virtual void init() { std::cout << "A init !&qu…

纯HTML调用restfull api工具

<!DOCTYPE html> <html> <head><meta charset"UTF-8"><title>API调用工具</title><style>keyframes marquee {0% {transform: translateX(0%);}80% {transform: translateX(70%);}}.marquee {animation: marquee 2s linea…

机器学习——主成分分析(PCA,未完)

略略翻了下书&#xff0c;差点儿窒息在床上… 看了几个博主的笔记&#xff0c;有点儿头疼 不知道是不是神经裂开生成新突触&#xff0c;还是脑细胞坏死前最后的呐喊 重点看了三篇&#xff0c;觉得非常惊艳&#xff0c;易于理解的 先看了主成分分析的原理详解&#xff0c;但还是…

硬件成本节省60%,四川华迪基于OceanBase的健康大数据数仓建设实践

导语&#xff1a;本文为四川华迪数据计算平台使用 OceanBase 替代 Hadoop 的实践&#xff0c;验证了 OceanBase 在性能和存储成本方面的优势&#xff1a;节省了 60% 的硬件成本&#xff0c;并将运维工作大幅减少&#xff0c;从 Hadoop 海量组件中释放出来&#xff1b;一套系统处…

21天打卡掌握java基础操作

Java安装环境变量配置-day1 参考&#xff1a; https://www.runoob.com/w3cnote/windows10-java-setup.html 生成class文件 java21天打卡-day2 输入和输出 题目&#xff1a;设计一个程序&#xff0c;输入上次考试成绩&#xff08;int&#xff09;和本次考试成绩&#xff0…

华为云云耀云服务器 L 实例使用,从性能、性价比、易用性、稳定性和安全性等方面进行评测

华为云云耀云服务器 L 实例是一款面向中小企业和开发者的云服务器产品。下面我们将从性能、性价比、易用性、稳定性和安全性等方面进行评测&#xff0c;并将其与同类产品进行对比。 性能 华为云云耀云服务器 L 实例基于最新的处理器技术&#xff0c;具备卓越的计算性能和响应速…

如何用工业树莓派和MQTT平台打通OT和IT?

一、应用设备 OT端设备&#xff1a;步进电机&#xff0c;MODBUS TCP远程I/O模块&#xff0c;PLC设备 边缘侧设备&#xff1a;宏集工业树莓派&#xff1b; IT端设备&#xff1a;PC、安卓手机&#xff1b; IT端软件&#xff1a;宏集HiveMQ MQTT通信平台 二、原理 宏集工业树…

iOS 中,isa 指针

每个对象都有 isa 指针&#xff0c;指向对象所属的类。例如类 NSString 其实是类对象。 类对象产生于编译期&#xff0c;单例。 类对象有 isa 指针指向对应元类&#xff0c;元类&#xff08;metaclass&#xff09;中保存了创建类对象以及类方法所需的所有信息。 struct objc_…

vue 后端返回二进制流-前端通过blob对象下载文件-图片

前言 在实际开发中我们经常会遇见下载文件的场景&#xff0c;比如下载合同&#xff0c;下载文件 下载文件有2种方式&#xff0c;一种是后端返回二进制流&#xff0c;前端通过blob对象接受根据不同类型下载 还有一种把地址直接在浏览器新窗口打开浏览器打开pdf可以预览和下载&…

react实现一维表格、键值对数据表格key value表格

UI画的需求很抽象&#xff0c;直接把数据铺开&#xff0c;不能直接用antd组件了 上一行是name&#xff0c;下一行是value&#xff0c;总数不定&#xff0c;最后前端还要显示求和 class OneDimensionTable extends React.Component { render() {const { data } this.props;le…

Linux安装node_exporter使用grafana进行服务器监控

文章目录 linux安装node_exporter修改node_exporter端口服务器安装grafana服务器安装prometheus将linux的noe_exporter配置到prometheus配置文件中导入linux服务器的模板,id: 16098常用exporter安装下载 linux安装node_exporter 要在CentOS 7.6.1810 (Core)上安装node_exporte…

网安顶刊IEEE Transactions on Dependable and Secure Computing

安全顶刊论文列表 写在最前面IEEE Transactions on Dependable and Secure ComputingTable of Contents&#xff08;March-April 2023&#xff09;Volume 20, Issue 2Table of Contents&#xff08;Sept.-Oct. 2023&#xff09;Volume 20, Issue 5 写在最前面 为了给自己找论文…

2023_Spark_实验十九:SparkStreaming入门案例

SparkStreaming入门案例 一、准备工作 二、任务分析 三、官网案例 四、开发NetWordCount 一、准备工作 实验环境&#xff1a;netcat 安装nc&#xff1a;yum install -y nc 二、任务分析 将nc作为服务器端&#xff0c;用户产生数据&#xff1b;启动sparkstreaming案例中的客户端…

【SA8295P 源码分析 (二)】64 - QNX 与 Android GVM 显示 Dump 图片方法汇总

【SA8295P 源码分析】64 - QNX 与 Android GVM 显示 Dump 图片方法汇总 一、QNX侧1.1 surfacedump 功能1.2 screenshot 功能二、Android GVM 侧2.1 screencap -p 导出 PNG 图片2.2 screencap 不加 -p 参数,导出 RGB32 图片2.3 dumpsys SurfaceFlinger --display-id 方法系列文…

php获取农历日期节日

代码地址&#xff1a;php获取农历日期节日-遇见你与你分享 <?php $c new DayService(); $today$c->convertSolarToLunar(date(Y),date(m),date(d)); $time "农历".$today[1].$today[2]."日";class DayService {var $MIN_YEAR 1891;var $MAX_YEAR …

mac电脑zsh: command not found: adb

“zsh: command not found: adb” 的解决方法&#xff1a; 前提 已经成功安装了 Android Studio. 打开 iTerm 终端依次输入下面命令&#xff1a; echo export ANDROID_HOME/Users/$USER/Library/Android/sdk >> ~/.zshrc echo export PATH${PATH}:$ANDROID_HOME/tool…

NIO IN:技术蔚来的首次「大阅兵」

宝山&#xff0c;上海第一钢铁厂旧址。 上周&#xff0c;蔚来在这里点亮金色炉台&#xff0c;2500 立方米高炉&#xff0c;浓重的工业气质与古典凝重的光影交织&#xff0c;蔚来 NIO IN 用科技的进步呼应那个火红的年代。 这是蔚来第一次开科技发布会&#xff0c;为了全方位展…

通过内网穿透快速搭建公网可访问的Spring Boot接口调试环境

&#x1f525;博客主页&#xff1a; 小羊失眠啦 &#x1f516;系列专栏&#xff1a; C语言 、Cpolar、Linux ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 文章目录 前言1. 本地环境搭建1.1 环境参数1.2 搭建springboot服务项目 2. 内网穿透2.1 安装配置cpolar内网穿透2.1.1 …

通讯协议学习之路:RS485协议理论

通讯协议之路主要分为两部分&#xff0c;第一部分从理论上面讲解各类协议的通讯原理以及通讯格式&#xff0c;第二部分从具体运用上讲解各类通讯协议的具体应用方法。 后续文章会同时发表在个人博客(jason1016.club)、CSDN&#xff1b;视频会发布在bilibili(UID:399951374) 序&…