2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > 用Qt将一组静态连续图片制作成动图(定时器和QPixmap实现)

用Qt将一组静态连续图片制作成动图(定时器和QPixmap实现)

时间:2022-04-19 23:22:55

相关推荐

用Qt将一组静态连续图片制作成动图(定时器和QPixmap实现)

效果图

由于视频大小限制和录制软件的原因,此图效果可能不是很好,在工程运行生成的Dialog窗口中,效果是非常不错的

项目文件

建立项目后,找到项目路径,建立新的文件夹,命名时不要出现中文,将静态连续图片导入到该新建的文件夹中,回到Qt Creator中,在项目中新建资源文件,并导入图片

完成后的项目文件如图所示

备注:

如果资源文件过多,可在pro文件中添加代码:

CONFIG += resources_big

以防止 error:out of memory allocating

代码:

dialog.h:

//dialog.h#ifndef DIALOG_H#define DIALOG_H#include <QDialog>QT_BEGIN_NAMESPACEnamespace Ui {class Dialog; }QT_END_NAMESPACEclass Dialog : public QDialog{Q_OBJECTpublic:Dialog(QWidget *parent = nullptr);~Dialog();void paintEvent(QPaintEvent * event);void timerEvent(QTimerEvent * event);int counter;void MyPixmap();private:QPixmap PixmapBox[100];Ui::Dialog *ui;};#endif // DIALOG_H

在此头文件中

public:声明了两个事件 —— 绘图事件和定时器事件,一个int型变量counter(计数器),一个函数MyPixmap()

private:私有成员PixmapBox[100],这就像是一个有100个元素的数组,每个元素都是一个QPixmap类

dialog.cpp:

//dialog.cpp#include "dialog.h"#include "ui_dialog.h"#include <QPainter>#include <QPixmap>Dialog::Dialog(QWidget *parent): QDialog(parent), ui(new Ui::Dialog){ui->setupUi(this);this->resize( QSize( 768, 432 ));MyPixmap();counter = 0;startTimer(50);}Dialog::~Dialog(){delete ui;}void Dialog::paintEvent(QPaintEvent * event){Q_UNUSED(event);//event参数未使用QPainter painter(this);QRect q1(0,0,1920,1080);QRect q2(0,0,width(),height());painter.drawPixmap(q2,PixmapBox[counter],q1);}void Dialog::timerEvent(QTimerEvent *event){Q_UNUSED(event);//event参数未使用counter++;if(counter >= 100)counter = 0;repaint();}void Dialog::MyPixmap(){for(int i = 0;i < 100;i++){QString fileName = QString("://Katou Megumi_000/Katou Megumi_0%0.jpg").arg(i,2,10,QLatin1Char('0'));QPixmap map(fileName);PixmapBox[i] = map;}}

构造函数中,语句

this->resize( QSize( 768, 432 ));

将窗口大小改变,建议按照图片分辨率进行等比拉伸

然后,调用了MyPixmap()函数,转到它的定义,定义中的这段代码

for(int i = 0;i < 100;i++){QString fileName = QString("://Katou Megumi_000/Katou Megumi_0%0.jpg").arg(i,2,10,QLatin1Char('0'));QPixmap map(fileName);PixmapBox[i] = map;}

QString fileName,声明一个名为fileName的类,内容是string类型": //Katou Megumi_000/Katou Megumi_0%0.jpg",arg函数用于替代字符串中的百分值,也就是

i=0时,fileName=": //Katou Megumi_000/Katou Megumi_000.jpg",

i=1时,fileName=": //Katou Megumi_000/Katou Megumi_001.jpg"

i=99时,fileName=": //Katou Megumi_000/Katou Megumi_099.jpg"

参数中的2是指定填充到并填充字符fillChar= QLatin1Char('0 '))(数字0,ASCII 48)的最小空间量

参数中的10是基参数指定将整数a转换为字符串时要使用的基,表示10进制

(我的理解可能不正确,欢迎指正,详见Qt帮助文档)

如果是从001.jpg开始,将arg参数列表中的i替换为i+1即可,当资源文件超过一百时,以200为例

for(int i = 0;i < 100;i++){QString fileName = QString("://Katou Megumi_000/Katou Megumi_0%0.jpg").arg(i,2,10,QLatin1Char('0'));QPixmap map(fileName);PixmapBox[i] = map;}for(int i = 100;i < 200;i++){QString fileName = QString("://Katou Megumi_000/Katou Megumi_%0.jpg").arg(i,2,10,QLatin1Char('0'));QPixmap map(fileName);//注意到字符串中0的数量的改变PixmapBox[i] = map;}

fileName的内容填充好后,用QPixmap类将图片传入,并将此QPixmap的类传入到PixmapBox[]的数组中,以便调用

然后回到构造函数,将counter(计数器)初始化,启用定时器,定时器每隔50毫秒启动一次,间隔取决于帧率,由于没有结束语句killTimer(),定时器会一直发生,定时器发生时,调用timerEvent(QTimerEvent *event),转到timerEvent(QTimerEvent *event)

counter++;if(counter >= 100)counter = 0;repaint();

计数器自加,用于切换帧,如果counter>=100时,即所有的帧都播放完毕后,counter赋值为0,repaint()调用此counter值下的paintEvent(QPaintEvent *event)事件,转到

paintEvent(QPaintEvent *event)

QPainter painter(this);QRect q1(0,0,1920,1080);QRect q2(0,0,width(),height());painter.drawPixmap(q2,PixmapBox[counter],q1);}

QPaint painter(this)创建绘图对象,q1为源,q2为目标,源矩形从坐标(0,0)起,宽为1920,高为1080,参照资源图片的分辨率,目标矩形从坐标(0,0)起,获取Dialog的宽和高,绘图对象绘制源矩形大小的QPixmap类,此类被储存在PixmapBox[]的数组中,通过计数器的当前值进行调用,然后绘图对象将其拉伸到目标矩形的大小,此后,资源图片正好铺满整个Dialog窗口

备注:

出现了此情况,是因为函数参数未使用,这是正常的现象,个人认为此警告意义不大

解决办法:在该函数下添加语句

Q_UNUSED(event);//event参数未使用

参考:

Qt下编译警告warning: unused parameter参数未使用(/lvdepeng123/article/details/79252968)

解决cc1plus.exe: error: out of memory allocating

等博客

个人初学,理解尚浅,若有错误,欢迎指正

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。