• 2911阅读
  • 9回复

Qt Gif转字符动画 [复制链接]

上一主题 下一主题
离线305750665
 

图酷模式  只看楼主 倒序阅读 楼主  发表于: 2019-05-09
效果图

















代码
  1. const int limit_max_pixmap_cache = 5;
  2. char toChar(int g)
  3. {
  4.     if (g <= 30) {
  5.         return '#';
  6.     }
  7.     else if (g > 30 && g <= 60) {
  8.         return '&';
  9.     }
  10.     else if (g > 60 && g <= 120) {
  11.         return '$';
  12.     }
  13.     else if (g > 120 && g <= 150) {
  14.         return '*';
  15.     }
  16.     else if (g > 150 && g <= 180) {
  17.         return 'o';
  18.     }
  19.     else if (g > 180 && g <= 210) {
  20.         return '!';
  21.     }
  22.     else {
  23.         return ' ';
  24.     }
  25. }
  26. int rgbtoGray(int r, int g, int b)
  27. {
  28.     return (int)((((quint32)((r << 5) + (r << 2) + (r << 1))) + (quint32)((g << 6) + (g << 3) + (g << 1) + g)
  29.         + (quint32)((b << 4) - b)) >> 7);
  30. }
  31. QPixmap setImage(const QImage &image)
  32. {
  33.     const int ih = image.height();
  34.     const int iw = image.width();
  35.     QPixmap txtImage(iw, ih);
  36.     txtImage.fill(Qt::transparent);
  37.     QPainter painter(&txtImage);
  38.     painter.setBrush(Qt::NoBrush);
  39.     painter.setPen(QColor::fromHsl(rand() % 360, rand() % 256, rand() % 200));
  40.     QFont font = painter.font();
  41.     font.setPixelSize(7);
  42.     font.setFamily("Microsoft YaHei");
  43.     painter.setFont(font);
  44.     
  45.     for (int i = 0; i < iw; i+= 7)
  46.     {
  47.         for (int j = 0; j < ih; j+= 7)
  48.         {
  49.             const QRgb&& pixel = image.pixel(i, j);
  50.             int r = qRed(pixel);
  51.             int g = qGreen(pixel);
  52.             int b = qBlue(pixel);
  53.             int gray = rgbtoGray(r, g, b);
  54.             char c = toChar((int)gray);
  55.             painter.drawText(i, j, QChar(c));
  56.         }
  57.     }
  58.     return txtImage;
  59. }
  60. MainWindow::MainWindow(QWidget *parent)
  61.     : QWidget(parent)
  62. {
  63.     ui.setupUi(this);
  64.     m_movie = getMovie(":/MainWindow/Resources/1.gif");
  65.     m_movieFrameCount = m_movie->frameCount();
  66.     m_curplayFrame = 0;
  67.     m_movie->jumpToFrame(0);
  68.     for (int i = 0; i < limit_max_pixmap_cache; i++){
  69.         m_cachePixmap.insert(i, setImage(m_movie->currentImage()));
  70.         m_srcCachePixmap.insert(i, m_movie->currentPixmap());
  71.         m_movie->jumpToNextFrame();
  72.     }
  73.     updateTextPixmap();
  74. }
  75. MainWindow::~MainWindow()
  76. {
  77.     QThreadPool::globalInstance()->clear();
  78.     QThreadPool::globalInstance()->waitForDone(3000);
  79. }
  80. void MainWindow::updateTextPixmap()
  81. {
  82.     int curNumber = m_movie->currentFrameNumber();
  83.     if (m_cachePixmap.contains(m_curplayFrame)){
  84.         ui.imageLabel->setPixmap(m_cachePixmap.value(m_curplayFrame));
  85.         ui.giflabel->setPixmap(m_srcCachePixmap.value(m_curplayFrame));
  86.         m_cachePixmap.take(m_curplayFrame);
  87.         m_srcCachePixmap.take(m_curplayFrame);
  88.         ThradFunctionTask* task = new ThradFunctionTask;
  89.         int curplayFrame = m_curplayFrame;
  90.         QImage image = m_movie->currentImage();
  91.         task->FNBind([this, curNumber, curplayFrame, image](){
  92.             m_cachePixmap.insert(curNumber, setImage(image));
  93.             m_srcCachePixmap.insert(curNumber, QPixmap::fromImage(image));
  94.         });
  95.         QThreadPoolManager::getInstance()->AddTask(task);
  96.     }
  97.     else{
  98.         qDebug() << "totalframe = " << m_movieFrameCount << " not find = " << m_curplayFrame;
  99.     }
  100.     m_curplayFrame++;
  101.     if (m_curplayFrame >= m_movieFrameCount)
  102.         m_curplayFrame = 0;
  103.     m_movie->jumpToNextFrame();
  104.     QTimer::singleShot(m_movie->speed(), this, &MainWindow::updateTextPixmap);
  105. }
  106. QMovie* MainWindow::getMovie(const QString& path)
  107. {
  108.     if (m_movie == nullptr)
  109.         m_movie = new QMovie(this);
  110.     if (m_movie->state() == QMovie::NotRunning){
  111.         m_movie->setFileName(path);
  112.         m_movie->jumpToFrame(0);
  113.         m_movie->stop();
  114.     }
  115.     return  m_movie;
  116. }


更多精彩:欢迎访问雨田哥博客
雨田哥: 群号:853086607
QQ: 3246214072

刘典武-feiyangqingyun:专业各种自定义控件编写+UI定制+输入法定制+视频监控+工业控制+仪器仪表+嵌入式linux+各种串口网络通信,童叟无欺,量大从优,欢迎咨询购买定制!QQ:517216493

只看该作者 1楼 发表于: 2019-05-09
就不能放个工程吗
离线cj123sn

只看该作者 2楼 发表于: 2019-05-10
雨田哥作品,总能眼前一亮.
离线xdh873939316

只看该作者 3楼 发表于: 2019-05-10
雨田哥,能否讲下大致的原理?
离线305750665

只看该作者 4楼 发表于: 2019-05-10
回 cj123sn 的帖子
cj123sn:雨田哥作品,总能眼前一亮. (2019-05-10 08:23) 

雨田哥: 群号:853086607
QQ: 3246214072

刘典武-feiyangqingyun:专业各种自定义控件编写+UI定制+输入法定制+视频监控+工业控制+仪器仪表+嵌入式linux+各种串口网络通信,童叟无欺,量大从优,欢迎咨询购买定制!QQ:517216493
离线305750665

只看该作者 5楼 发表于: 2019-05-10
回 xdh873939316 的帖子
xdh873939316:雨田哥,能否讲下大致的原理?[表情]  (2019-05-10 08:32) 

博客有篇地址。上面有叙述
雨田哥: 群号:853086607
QQ: 3246214072

刘典武-feiyangqingyun:专业各种自定义控件编写+UI定制+输入法定制+视频监控+工业控制+仪器仪表+嵌入式linux+各种串口网络通信,童叟无欺,量大从优,欢迎咨询购买定制!QQ:517216493
离线toby520

只看该作者 6楼 发表于: 2019-05-10
      我也想抄  看到widget做的好东西 都想搬到qml上面去
QtQML多多指教开发社区 http://qtclub.heilqt.com
将QtCoding进行到底
关注移动互联网,关注金融
开发跨平台客户端,服务于金融行业
专业定制界面
群号:312125701   373955953(qml控件定做)
离线liudianwu

只看该作者 7楼 发表于: 2019-05-10
欢迎关注微信公众号:Qt实战/Qt入门和进阶(各种开源作品、经验整理、项目实战技巧,专注Qt/C++软件开发,视频监控、物联网、工业控制、嵌入式软件、国产化系统应用软件开发) QQ:517216493  WX:feiyangqingyun  QQ群:751439350
离线305750665

只看该作者 8楼 发表于: 2019-05-10
回 toby520 的帖子
toby520:[表情]  [表情]  [表情]  我也想抄  看到widget做的好东西 都想搬到qml上面去
 (2019-05-10 09:29) 

多多大佬QML分分钟的事
雨田哥: 群号:853086607
QQ: 3246214072

刘典武-feiyangqingyun:专业各种自定义控件编写+UI定制+输入法定制+视频监控+工业控制+仪器仪表+嵌入式linux+各种串口网络通信,童叟无欺,量大从优,欢迎咨询购买定制!QQ:517216493
离线305750665

只看该作者 9楼 发表于: 2019-05-10
回 liudianwu 的帖子
liudianwu:[表情] [表情] [表情] [表情] [表情]  (2019-05-10 10:08) 

刘总优化下
雨田哥: 群号:853086607
QQ: 3246214072

刘典武-feiyangqingyun:专业各种自定义控件编写+UI定制+输入法定制+视频监控+工业控制+仪器仪表+嵌入式linux+各种串口网络通信,童叟无欺,量大从优,欢迎咨询购买定制!QQ:517216493
快速回复
限100 字节
 
上一个 下一个