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

news/2025/2/22 16:07:35

目录

一、用手搓(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

待研究


http://www.niftyadmin.cn/n/5204491.html

相关文章

linux ld 链接器学习笔记

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

[MICROSAR Adaptive] --- Persistency

1 persistency 概念介绍 percistency持久化,上一集我们介绍过 从一个应用程序的角度来看 它能使用的API可以分为三类,ara::per的API就属于这里的第二类direct API,只需要编译链接相应的库就可以直接使用了。我们先来了解ara::per的主要功能,ara::per提供持久化存储相关的,…

2023 年 亚太赛 APMCM ABC题 国际大学生数学建模挑战赛 |数学建模完整代码+建模过程全解全析

当大家面临着复杂的数学建模问题时&#xff0c;你是否曾经感到茫然无措&#xff1f;作为2022年美国大学生数学建模比赛的O奖得主&#xff0c;我为大家提供了一套优秀的解题思路&#xff0c;让你轻松应对各种难题。 以五一杯 A题为例子&#xff0c;以下是咱们做的一些想法呀&am…

【Python 千题 —— 基础篇】奇数列表

题目描述 题目描述 创建奇数列表。使用 for 循环创建一个包含 20 以内奇数的列表。 输入描述 无输入。 输出描述 输出创建的列表。 示例 示例 ① 输出&#xff1a; 创建的奇数列表为: [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]代码讲解 下面是本题的代码&#xff1a; #…

如何用cmd命令快速搭建FTP服务

环境&#xff1a; Win10专业版 问题描述&#xff1a; 如何用cmd命令快速搭建FTP服务 解决方案&#xff1a; 1.输入以下命令来安装IIS&#xff08;Internet Information Services&#xff09;&#xff1a; dism /online /enable-feature /featurename:IIS-FTPServer /all …

有msvcr120.dll下载官网么?快速修复msvcr120.dll的方法

首先要解释一下&#xff0c;msvcr120.dll下载官网是没有的&#xff01;是没有的&#xff01;msvcr120.dll下载都是没有官网的&#xff0c;如果你非要说有个正规的&#xff0c;那就是从Microsoft 的官方网站下载&#xff0c;我们下面会有介绍说明。出现找不到msvcr120.dll的提示…

Java判断字符串当中是否包含中文内容

代码如下&#xff1a; public static void main(String[] args_) throws Exception {String str1 "zhang张123";String str2 "zhang123";System.out.println(checkStringType(str1)); // 包含中文字符System.out.println(checkStringType(str2)); // 不包…

Java如何获取泛型类型

泛型&#xff08;Generic&#xff09; 泛型允许程序员在强类型程序设计语言中编写代码时使用一些以后才指定的类型&#xff0c;在实例化时作为参数指明这些类型。各种程序设计语言和其编译器、运行环境对泛型的支持均不一样。Ada、Delphi、Eiffel、Java、C#、F#、Swift 和 Vis…