Qt实现图片旋转的几种方式(全)

目录

一、用手搓(QPainter)

二、使用 QGraphicsView 和 QGraphicsPixmapItem

三、使用 QTransform 实现图像旋转

四、利用 OpenGL


实现旋转图像的效果有几种不同的方法,其中常见的包括:

  1. 手动旋转绘制: 使用 QPainter 的旋转函数,手动计算旋转后的坐标并绘制图像。这种方式需要自己处理旋转后的坐标变换,相对复杂一些。

  2. 使用 QGraphicsView 和 QGraphicsPixmapItem: 使用 QGraphicsView 架构绘制图形对象,并在 QGraphicsScene 中添加 QGraphicsPixmapItem,然后通过旋转 QGraphicsPixmapItem 实现图像旋转。

  3. 使用 QTransform: 使用 QTransform 类来应用变换,通过旋转矩阵来对图像进行旋转,然后使用 QPainter 绘制旋转后的图像。这种方法能够简化坐标变换的操作。

  4. 利用 OpenGL: 利用 Qt 的 QOpenGLWidget 和 OpenGL 的旋转操作,在 OpenGL 上下文中进行图像的绘制和旋转。这种方法适用于需要更高级别的图形操作和性能要求较高的场景。

每种方法都有其特点和适用场景,选择其中一种取决于你的需求和熟悉程度。通常情况下,QTransform 是实现图像旋转最常用且较为简便的方式。

一、用手搓(QPainter

  1. 创建绘图设备(QPainter): 首先,需要创建一个 QPainter 对象,用于执行绘图操作。

  2. 设置绘图参数: 在进行绘图之前,可以通过 QPainter 的函数设置渲染参数,如反锯齿等。

  3. 加载图像: 使用 QPixmap 加载需要绘制的图像。

  4. 设置绘图变换: 使用 QPainter 的变换函数(例如 translate、rotate 等),将绘图坐标系转换到图像的中心,并按需求进行旋转。

  5. 绘制图像: 使用 QPainter 的 drawPixmap 函数,在指定的位置绘制图像。

  6. 重置绘图变换(可选): 如果在绘制其他内容之前需要恢复坐标系变换,则可以使用 QPainter 的 resetTransform 函数重置坐标系。

  7. 完成绘图: 绘图完成后,程序会自动将绘图设备的内容显示到窗口上,或者在需要时手动调用 update 函数触发窗口的重绘。

​手搓代码:https://download.csdn.net/download/qq_43445867/88562187

二、使用 QGraphicsView 和 QGraphicsPixmapItem

1、创建一个 QGraphicsScene 对象。然后加载图像到 QPixmap 中,

2、创建 QGraphicsPixmapItem 对象,并将图像加载到这个 QGraphicsPixmapItem 中。

3、分别使用 setPos()setRotation() 函数,设置图像的位置和旋转角度。

4、将 QGraphicsPixmapItem 添加到 QGraphicsScene

5、创建一个 QGraphicsView 对象,并将 QGraphicsScene 设置为 QGraphicsView 的场景,最终显示了这个 QGraphicsView

6、通过修改 setPos()setRotation() 函数中的参数,可以设置图像的位置和旋转角度。这种方法相比手动绘制更简单,并且使用 QGraphicsViewQGraphicsPixmapItem 更方便地进行图像的操作和显示。

7、创建一个定时器 QTimer,并将其连接到一个 Lambda 函数,Lambda 函数中每次定时器超时时都会更新图像的旋转角度。在每个超时事件中,图像的旋转角度增加 1 度,并通过 setRotation() 函数应用于 QGraphicsPixmapItem,从而使图像持续旋转。然后使用 timer.start() 启动定时器,并设定每 30 毫秒更新一次旋转角度

#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsPixmapItem>
#include <QPixmap>
#include <QTimer>
​
int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
​
    // 创建 QGraphicsScene
    QGraphicsScene scene;
​
    // 加载图像到 QPixmap
    QPixmap pixmap("statI.png");
​
    // 创建 QGraphicsPixmapItem 并将图像加载到 QGraphicsPixmapItem 中
    QGraphicsPixmapItem *pixmapItem = new QGraphicsPixmapItem(pixmap);
​
    // 设置图像的旋转中心点为图像中心
    pixmapItem->setTransformOriginPoint(pixmap.width() / 2, pixmap.height() / 2);
​
    // 将 QGraphicsPixmapItem 添加到 QGraphicsScene 中
    scene.addItem(pixmapItem);
​
    // 创建 QGraphicsView,并将 QGraphicsScene 设置为它的场景
    QGraphicsView view(&scene);
​
    // 显示 QGraphicsView
    view.show();
​
    // 创建定时器,并连接到槽函数以持续更新旋转角度
    QTimer timer;
    QObject::connect(&timer, &QTimer::timeout, [&]() {
        static qreal rotationAngle = 0.0;
        rotationAngle += 1.0; // 每次增加旋转角度
​
        // 将旋转角度应用于 QGraphicsPixmapItem
        pixmapItem->setRotation(rotationAngle);
    });
    timer.start(30); // 每 30 毫秒更新一次旋转角度
​
    return app.exec();
}

三、使用 QTransform 实现图像旋转

使用 Qt 提供的图形组件和定时器来实现图像的加载和旋转,通过设置合适的中心点以及应用 QTransform 进行变换操作,达到了让图像围绕自身中心点旋转的效果。

  // 创建 QTransform 对象,并应用旋转变换
  QTransform transform;
  transform.translate(pixmap.width() / 2, pi
  transform.rotate(rotationAngle); // 绕中心点旋转
  transform.translate(-pixmap.width() / 2, -
  // 将变换应用于 QGraphicsPixmapItem
  pixmapItem->setTransform(transform);

通过使用 QGraphicsSceneQGraphicsViewQGraphicsPixmapItem 这些 Qt 图形组件来显示图像,并使用 QTimer 定时器来控制图像的旋转。

  1. 加载图像: 使用 QPixmap 加载图片,并将其放置在 QGraphicsPixmapItem 中,然后将该项添加到 QGraphicsScene 中,最终显示在 QGraphicsView 中。

  2. 设置中心点:QGraphicsPixmapItem 中使用 setTransformOriginPoint() 将图像的中心点设置为图像的中心。

  3. 定时旋转: 创建 QTimer 定时器,每当定时器超时时,更新旋转角度。在超时槽函数中,使用 QTransform 进行变换处理。首先移动图像的原点到中心点,然后进行旋转,最后再将原点移回原位置。这样就实现了图像围绕自身中心点持续旋转的效果。

  4. 显示图像:QGraphicsView 显示出来,图像会根据定时器的触发事件,在固定时间间隔内持续旋转显示。

#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsPixmapItem>
#include <QPixmap>
#include <QTransform>
#include <QTimer>

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    // 创建 QGraphicsScene
    QGraphicsScene scene;

    // 加载图像到 QPixmap
    QPixmap pixmap(":/path/to/your/image.png");

    // 创建 QGraphicsPixmapItem 并将图像加载到 QGraphicsPixmapItem 中
    QGraphicsPixmapItem *pixmapItem = new QGraphicsPixmapItem(pixmap);

    // 设置图像的中心点为原点
    pixmapItem->setTransformOriginPoint(pixmap.width() / 2, pixmap.height() / 2);

    // 将 QGraphicsPixmapItem 添加到 QGraphicsScene 中
    scene.addItem(pixmapItem);

    // 创建 QGraphicsView,并将 QGraphicsScene 设置为它的场景
    QGraphicsView view(&scene);

    // 显示 QGraphicsView
    view.show();

    // 创建定时器,并连接到槽函数以持续更新旋转角度
    QTimer timer;
    QObject::connect(&timer, &QTimer::timeout, [&]() {
        static qreal rotationAngle = 0.0;
        rotationAngle += 1.0; // 每次增加旋转角度

        // 创建 QTransform 对象,并应用旋转变换
        QTransform transform;
        transform.translate(pixmap.width() / 2, pixmap.height() / 2); // 将原点移动到中心
        transform.rotate(rotationAngle); // 绕中心点旋转
        transform.translate(-pixmap.width() / 2, -pixmap.height() / 2); // 将原点移回原位

        // 将变换应用于 QGraphicsPixmapItem
        pixmapItem->setTransform(transform);
    });
    timer.start(30); // 每 30 毫秒更新一次旋转角度

    return app.exec();
}

四、利用 OpenGL

待研究

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Qt开发流程】之富文本处理

描述 Scribe框架提供了一组类&#xff0c;用于读取和操作结构化的富文本文档。与Qt中以前的富文本支持不同&#xff0c;新的类集中在QTextDocument类上&#xff0c;而不是原始文本信息。这使开发者能够创建和修改结构化的富文本文档&#xff0c;而不必准备中间标记格式的内容。…

【C++】泛型编程 ⑫ ( 类模板 static 关键字 | 类模板 static 静态成员 | 类模板使用流程 )

文章目录 一、类模板使用流程1、类模板 定义流程2、类模板 使用3、类模板 函数 外部实现 二、类模板 static 关键字1、类模板 static 静态成员2、类模板 static 关键字 用法3、完整代码示例 将 类模板 函数声明 与 函数实现 分开进行编码 , 有 三种 方式 : 类模板 的 函数声明…

linux ld 链接器学习笔记

ld链接器笔记 1. 首先编写一段汇编代码 这里的汇编语法时 AT&T语法,是gcc原生支持的语法,底层使用 gas(gnu assembler) 完成汇编,相较于 Intel x86语法, AT&T 语法要更加古老,因此大多数人更加偏向于使用 Intel 的语法. nasm 编译器支持x86语法.自从2.10版本&#xf…

问鼎web服务

华子目录 www简介常见Web服务程序介绍&#xff1a;服务器主机主要数据浏览器网址及http介绍urlhttp请求方法 http协议请求的工作流程www服务器类型静态网站动态网站 快速安装Apache安装准备工作httpd所需目录主配置文件 实验操作 www简介 Web网络服务也叫www&#xff08;world…

晶振有哪几种?晶振旁边的两个电容起什么作用?

晶振可以分为普通晶振、温补晶振、压控晶振、恒温晶振、差分晶振。 普通晶振通常用作微处理器的时钟器件&#xff0c;主要应用于那些稳定度要求不要的设备中&#xff0c;例如电视机、微波炉。 温补晶振&#xff0c;在晶振内部采取了对晶体频率、温度特性进行补偿&#xff0c;已…

Vue3常用操作

一、Vue3项目构建 1、安装最新版本vue npm create vuelatest 2、选择需要的配置 3、进入项目 cd 项目名称 4、下载依赖 npm install 5、启动项目 npm run dev

数据结构—链表

链表结构-----“银行自助叫号” 链表&#xff08;Linked List&#xff09;是一种常见的数据结构&#xff0c;用于存储一个序列的元素。它由一系列结点组成&#xff0c;每个结点包含两个部分&#xff1a;数据部分和指针部分。数据部分存储着当前结点的数据&#xff0c;而指针部分…

CSDN最新最全pytest系列——pytest-base-url插件之配置可选的项目系统UR

前言 ①当我们的自动化代码完成之后&#xff0c;通常期望可以在不同的环境进行测试&#xff0c;此时可以将项目系统的URL单独拿出来&#xff0c;并且可以通过pytest.ini配置文件和支持pytest命令行方式执行。 ② pytest-base-url 是一个简单的pytest插件&#xff0c;它通过命…

12-25v转3.3v高清水下钓鱼摄像头电源供电芯片方案

高清水下钓鱼摄像头电源芯片方案&#xff1a;12-25V转3.3V&#xff0c;支持超宽电压输入范围和30米长线视频放大 在水下钓鱼摄像头设计中&#xff0c;为了实现高清画质和稳定的电源供应&#xff0c;需要一款能够将12-25V转换为3.3V输出的高效电源芯片。这款电源芯片不仅支持高…

【电路笔记】-电流源

电流源 文章目录 电流源1、概述1.1 理想电流源1.2 实际电流源1.3 连接规则 2、依赖电流2.1 压控电流源2.2 电流控制电流源 3、总结 本文为前面文章 电压源的延续&#xff0c;我们将在本文介绍电流源。 与电压源的情况类似&#xff0c;我们将首先介绍理想电流源的概念&#xff…

第二十章:多线程

进程 线程的特点 1.进程是资源分配的最小单位&#xff0c;线程是最小的执行单位 2.一个进程可以有多个线程 3.线程共享进程资源 package twentyth; public class ThreadTest extends Thread { public void run() { for (int i 1; i < 10; i) {//继承重…

Shell判断:模式匹配:case(三)

系统管理工具箱 1、需求&#xff1a;Linux提供的丰富的管理命令&#xff0c;用户管理&#xff0c;内存管理&#xff0c;磁盘管理&#xff0c;进程管理&#xff0c;日志管理&#xff0c;文件管理&#xff0c;软件管理&#xff0c;网络管理等等数十个工具包。如果你能通过shell编…

二十、虚拟机网络配置

1、Linux网络配置原理 我自己Linux虚拟机的IP地址是&#xff1a;192.168.159.131 vmnet8&#xff1a;192.168.159.1 无线网卡&#xff1a;192.168.159.1 2、查看网络IP和网关 查看虚拟网络编辑器和修改IP地址 如果把这个位置的子网IP换成&#xff1a;192.168.8.0的话重启虚拟机…

【兔子王赠书第8期】AI短视频制作一本通: 文本生成视频+图片生成视频+视频生成视频

文章目录 写在前面推荐图书关键点内容简介作者简介推荐理由写在后面 写在前面 1本书精通AI短视频制作&#xff0c;文本生成视频图片生成视频视频生成视频AI短视频应用&#xff01;高效视频制作技巧&#xff0c;助你快速成长为行业大咖&#xff01; 推荐图书 《AI短视频制作一…

Java小游戏之飞翔的小鸟

创建三个包&#xff0c;存放代码。把图片放进文件中 APP包&#xff08;运行&#xff09; GameApp类 package APP; import mian.GameFrame;public class GameApp {public static void main(String[] args) {new GameFrame();} } mian包&#xff08;主内容&#xff09; Barrie…

SQL基础理论篇(九):存储过程

文章目录 简介存储过程的形式定义一个存储过程使用delimiter定义语句结束符存储过程中的三种参数类型流控制语句 存储过程的优缺点参考文献 简介 存储过程Stored Procedure&#xff0c;SQL中的另一个重要应用。 前面说的视图&#xff0c;只能勉强跟编程中的函数相似&#xff…

2023年危险化学品生产单位安全生产管理人员证模拟考试题库及危险化学品生产单位安全生产管理人员理论考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年危险化学品生产单位安全生产管理人员证模拟考试题库及危险化学品生产单位安全生产管理人员理论考试试题是由安全生产模拟考试一点通提供&#xff0c;危险化学品生产单位安全生产管理人员证模拟考试题库是根据危…

Unsupervised MVS论文笔记

Unsupervised MVS论文笔记 摘要1 引言2 相关工作3 实现方法 Tejas Khot and Shubham Agrawal and Shubham Tulsiani and Christoph Mertz and Simon Lucey and Martial Hebert. Tejas Khot and Shubham Agrawal and Shubham Tulsiani and Christoph Mertz and Simon Lucey and …

【java】想要限制每次查询的结果集不能超过10000行,该如何实现?

文章目录 前言 前言 对于一些Saas化软件&#xff0c;当某个租户在执行查询SQL时&#xff0c;如果查询条件出现了BUG&#xff0c;导致去查了所有租户的数据&#xff0c;这种情况是非常严重的&#xff0c;此时就需要在架构层面做限制&#xff0c;禁止一些特殊SQL的执行&#xff…

Axios 请求响应结果的结构

发送请求 this.$axios.get(https://apis.jxcxin.cn/api/title?urlhttps://apis.jxcxin.cn/,{params: {id: 10}}).then(res > {console.log(res)})输出返回结果 confing 请求时的配置对象&#xff0c;如果请求的url&#xff0c;请求的方法&#xff0c;请求的参数&#xff0c…