qt用多线程实现GIF转字符动画代码项目
时间: 2024-02-16 09:04:10 浏览: 29
以下是一个简单的 Qt 多线程实现 GIF 转字符动画的示例代码:
```cpp
#include <QCoreApplication>
#include <QImage>
#include <QPainter>
#include <QThread>
#include <QMutex>
#include <QDebug>
class GifToAsciiWorker : public QObject
{
Q_OBJECT
public:
GifToAsciiWorker(const QString& filePath, int delay, int width, int height)
: m_filePath(filePath)
, m_delay(delay)
, m_width(width)
, m_height(height)
{}
signals:
void imageReady(const QString& image);
public slots:
void process()
{
QImageReader reader(m_filePath);
reader.setDecideFormatFromContent(true);
// 获取 GIF 图像的帧数
int frameCount = reader.imageCount();
for (int i = 0; i < frameCount; i++)
{
QImage image = reader.read();
image = image.scaled(m_width, m_height, Qt::KeepAspectRatio);
// 将图像转换成 ASCII 码
QString asciiImage = imageToAscii(image);
// 发送信号,通知主线程处理结果
emit imageReady(asciiImage);
// 延时指定的时间
QThread::msleep(m_delay);
}
}
private:
QString m_filePath;
int m_delay;
int m_width;
int m_height;
// 将图像转换成 ASCII 码
QString imageToAscii(const QImage& image)
{
QString asciiImage;
for (int y = 0; y < image.height(); y++)
{
for (int x = 0; x < image.width(); x++)
{
QColor color = image.pixelColor(x, y);
int gray = qGray(color.rgb());
// 根据灰度值选择对应的 ASCII 字符
if (gray >= 230)
{
asciiImage += " ";
}
else if (gray >= 200)
{
asciiImage += ".";
}
else if (gray >= 180)
{
asciiImage += "*";
}
else if (gray >= 160)
{
asciiImage += ":";
}
else if (gray >= 130)
{
asciiImage += "o";
}
else if (gray >= 100)
{
asciiImage += "&";
}
else if (gray >= 70)
{
asciiImage += "8";
}
else if (gray >= 50)
{
asciiImage += "#";
}
else
{
asciiImage += "@";
}
}
asciiImage += "\n";
}
return asciiImage;
}
};
class GifToAscii : public QObject
{
Q_OBJECT
public:
GifToAscii(const QString& filePath, int delay, int width, int height)
: m_filePath(filePath)
, m_delay(delay)
, m_width(width)
, m_height(height)
{
m_workerThread = new QThread();
m_worker = new GifToAsciiWorker(m_filePath, m_delay, m_width, m_height);
// 将 worker 移动到工作线程中
m_worker->moveToThread(m_workerThread);
// 连接信号和槽
connect(m_worker, SIGNAL(imageReady(QString)), this, SLOT(onImageReady(QString)));
connect(m_workerThread, SIGNAL(started()), m_worker, SLOT(process()));
connect(m_workerThread, SIGNAL(finished()), m_worker, SLOT(deleteLater()));
connect(m_workerThread, SIGNAL(finished()), m_workerThread, SLOT(deleteLater()));
// 启动工作线程
m_workerThread->start();
}
~GifToAscii()
{
// 停止工作线程
m_workerThread->quit();
m_workerThread->wait();
}
signals:
void finished();
public slots:
void onImageReady(const QString& image)
{
// 处理图像
qDebug() << image;
}
private:
QString m_filePath;
int m_delay;
int m_width;
int m_height;
QThread* m_workerThread;
GifToAsciiWorker* m_worker;
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 创建 GifToAscii 对象
GifToAscii* gifToAscii = new GifToAscii("test.gif", 100, 80, 60);
// 等待处理完成
QObject::connect(gifToAscii, SIGNAL(finished()), &a, SLOT(quit()));
return a.exec();
}
#include "main.moc"
```
在上面的代码中,我们创建了两个类:GifToAscii 和 GifToAsciiWorker。GifToAscii 类负责创建 GifToAsciiWorker 对象,并将其移动到工作线程中。GifToAsciiWorker 类则负责实际的图像处理工作。
在 GifToAsciiWorker 类的 process() 槽函数中,我们使用 QImageReader 读取 GIF 图像,并使用 imageToAscii() 函数将图像转换成 ASCII 码。然后,我们通过发射 imageReady() 信号将处理结果发送给主线程。
在 GifToAscii 类的 onImageReady() 槽函数中,我们将处理结果打印到控制台。最后,我们在 main() 函数中创建 GifToAscii 对象,并等待处理完成。