@[toc]

简述

1.今天无意间看到一位网友用Java实现了一个 GIF转字符动画的效果,看起来挺有意思的。然后看了下原理,用Qt也实现了一把。目前缺陷是计算过程中特别耗CPU,后面的网友们,希望你们能优化掉这个问题。

参考地址:【轻松一刻】Java制作字符动画

效果图

1.gif

2.gif

3.gif

核心代码

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


标签:Qt C++ Python



开发PC客户端,服务于金融行业 37091473(付费咨询)
沪ICP备14050191号 Copyright © 多多指教社区(群:312125701)
Tobyyi's QtQuick Example | Powered by NoderCMS