简述
1.今天无意间看到一位网友用Java实现了一个 GIF转字符动画的效果,看起来挺有意思的。然后看了下原理,用Qt也实现了一把。目前缺陷是计算过程中特别耗CPU,后面的网友们,希望你们能优化掉这个问题。
参考地址:【轻松一刻】Java制作字符动画
效果图
核心代码
const int limit_max_pixmap_cache = 5;
char toChar(int g)
{
if (g <= 30) {
return '#';
}
else if (g > 30 && g <= 60) {
return '&';
}
else if (g > 60 && g <= 120) {
return '$';
}
else if (g > 120 && g <= 150) {
return '*';
}
else if (g > 150 && g <= 180) {
return 'o';
}
else if (g > 180 && g <= 210) {
return '!';
}
else {
return ' ';
}
}
int rgbtoGray(int r, int g, int b)
{
return (int)((((quint32)((r << 5) + (r << 2) + (r << 1))) + (quint32)((g << 6) + (g << 3) + (g << 1) + g)
+ (quint32)((b << 4) - b)) >> 7);
}
QPixmap setImage(const QImage &image)
{
const int ih = image.height();
const int iw = image.width();
QPixmap txtImage(iw, ih);
txtImage.fill(Qt::transparent);
QPainter painter(&txtImage);
painter.setBrush(Qt::NoBrush);
painter.setPen(QColor::fromHsl(rand() % 360, rand() % 256, rand() % 200));
QFont font = painter.font();
font.setPixelSize(7);
font.setFamily("Microsoft YaHei");
painter.setFont(font);
for (int i = 0; i < iw; i+= 7)
{
for (int j = 0; j < ih; j+= 7)
{
const QRgb&& pixel = image.pixel(i, j);
int r = qRed(pixel);
int g = qGreen(pixel);
int b = qBlue(pixel);
int gray = rgbtoGray(r, g, b);
char c = toChar((int)gray);
painter.drawText(i, j, QChar(c));
}
}
return txtImage;
}
MainWindow::MainWindow(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
m_movie = getMovie(":/MainWindow/Resources/1.gif");
m_movieFrameCount = m_movie->frameCount();
m_curplayFrame = 0;
m_movie->jumpToFrame(0);
for (int i = 0; i < limit_max_pixmap_cache; i++){
m_cachePixmap.insert(i, setImage(m_movie->currentImage()));
m_srcCachePixmap.insert(i, m_movie->currentPixmap());
m_movie->jumpToNextFrame();
}
updateTextPixmap();
}
MainWindow::~MainWindow()
{
QThreadPool::globalInstance()->clear();
QThreadPool::globalInstance()->waitForDone(3000);
}
void MainWindow::updateTextPixmap()
{
int curNumber = m_movie->currentFrameNumber();
if (m_cachePixmap.contains(m_curplayFrame)){
ui.imageLabel->setPixmap(m_cachePixmap.value(m_curplayFrame));
ui.giflabel->setPixmap(m_srcCachePixmap.value(m_curplayFrame));
m_cachePixmap.take(m_curplayFrame);
m_srcCachePixmap.take(m_curplayFrame);
ThradFunctionTask* task = new ThradFunctionTask;
int curplayFrame = m_curplayFrame;
QImage image = m_movie->currentImage();
task->FNBind([this, curNumber, curplayFrame, image](){
m_cachePixmap.insert(curNumber, setImage(image));
m_srcCachePixmap.insert(curNumber, QPixmap::fromImage(image));
});
QThreadPoolManager::getInstance()->AddTask(task);
}
else{
qDebug() << "totalframe = " << m_movieFrameCount << " not find = " << m_curplayFrame;
}
m_curplayFrame++;
if (m_curplayFrame >= m_movieFrameCount)
m_curplayFrame = 0;
m_movie->jumpToNextFrame();
QTimer::singleShot(m_movie->speed(), this, &MainWindow::updateTextPixmap);
}
QMovie* MainWindow::getMovie(const QString& path)
{
if (m_movie == nullptr)
m_movie = new QMovie(this);
if (m_movie->state() == QMovie::NotRunning){
m_movie->setFileName(path);
m_movie->jumpToFrame(0);
m_movie->stop();
}
return m_movie;
}
工程文件
Qt交流大会 853086607 (收费群,用于后期群费用)
结尾
不定期上传新作品,解答群中作品相关问题。相关外,能解答则解答。欢迎大家一起探索Qt世界!相关工程,可以联系博主雨田哥:3246214072