qt中实现左右分割线_Qt项目中,实现屏幕截图并生成gif的详细示例(值得细读)...
總第50篇
平時我們在工作和學習的過程中,有時需要將桌面的某些動作截圖生成gif動圖,以更生動地呈現出來。目前有很多這樣的軟件,并且方便易使用,比如我經常使用的GifCam,軟件小巧,生成的圖片文件也比較小,非常優秀。它的界面如下圖所示(這里絕不是打廣告呀)。
那么,這種截圖后生成gif文件是如何用軟件實現的呢?
本文將詳細說明一下這種功能的實現思路,作為軟件設計的一種參考,也方便在以后的工程項目中借鑒與參照。
1.多張image圖片處理成gif圖片的實現
這個可以借助gif開源的類來實現,直接調用其中的方法,可以實現將多張圖片合并到一張gif圖片中去,并且這個類還是跨平臺的,方便在多平臺上實現。這里列舉幾個要用到的接口的實現,詳細的接口實現請查看完整的開源類文件(若找不到,可以聯系我,問我要)。
struct GifWriter { //這個是寫gif的結構體定義FILE *f;uint8_t *oldImage;bool firstFrame;}; //開始生成gif文件的接口bool GifBegin( GifWriter *writer, const char *filename,uint32_t width, uint32_t height,uint32_t delay, int32_t bitDepth = 8,bool dither = false ){(void)bitDepth;(void)dither; // Mute "Unused argument" warnings #if defined(_MSC_VER) && (_MSC_VER >= 1400)writer->f = 0;fopen_s(&writer->f, filename, "wb"); #elsewriter->f = fopen(filename, "wb"); #endifif(!writer->f) {return false;}writer->firstFrame = true;// allocatewriter->oldImage = (uint8_t *)GIF_MALLOC(width * height * 4);fputs("GIF89a", writer->f);// screen descriptorfputc(width & 0xff, writer->f);fputc((width >> 8) & 0xff, writer->f);fputc(height & 0xff, writer->f);fputc((height >> 8) & 0xff, writer->f);fputc(0xf0, writer->f); // there is an unsorted global color table of 2 entriesfputc(0, writer->f); // background colorfputc(0, writer->f); // pixels are square (we need to specify this because it's 1989)// now the "global" palette (really just a dummy palette)// color 0: blackfputc(0, writer->f);fputc(0, writer->f);fputc(0, writer->f);// color 1: also blackfputc(0, writer->f);fputc(0, writer->f);fputc(0, writer->f);if( delay != 0 ) {// animation headerfputc(0x21, writer->f); // extensionfputc(0xff, writer->f); // application specificfputc(11, writer->f); // length 11fputs("NETSCAPE2.0", writer->f); // yes, reallyfputc(3, writer->f); // 3 bytes of NETSCAPE2.0 datafputc(1, writer->f); // JUST BECAUSEfputc(0, writer->f); // loop infinitely (byte 0)fputc(0, writer->f); // loop infinitely (byte 1)fputc(0, writer->f); // block terminator}return true;}//向gif文件生成過程中寫入一幀數據的接口bool GifWriteFrame( GifWriter *writer, const uint8_t *image,uint32_t width, uint32_t height,uint32_t delay, int bitDepth = 8, bool dither = false ){if(!writer->f) {return false;}const uint8_t *oldImage = writer->firstFrame ? NULL : writer->oldImage;writer->firstFrame = false;GifPalette pal;GifMakePalette((dither ? NULL : oldImage), image, width, height, bitDepth, dither, &pal);if(dither) {GifDitherImage(oldImage, image, writer->oldImage, width, height, &pal);} else {GifThresholdImage(oldImage, image, writer->oldImage, width, height, &pal);}GifWriteLzwImage(writer->f, writer->oldImage, 0, 0, width, height, delay, &pal);return true;}2.定時生成圖片并記錄圖片
用定時器的singleShot()定時截取桌面的的一幀幀圖片,將圖片保存處理后送入到gif的GifWriteFrame() 接口,生成相應的動圖。這里關鍵在于從桌面上獲取截圖,要用到grabWindow()這個接口函數。
對于Qt5以前和版本, 這個接口函數是放在QPixmap中,獲取的圖片也是QPixmap格式的。對于Qt5以上的版本,這個接口是單獨放進了一個類,這個類叫QScreen,獲取的圖片也是QPixmap格式的。
其關鍵的兩個函數代碼示例如下:
//從桌面截圖并幀寫入到gif中 void GifWidget::saveImage() {if (!gifWriter) {return;}QScreen *screen = QApplication::primaryScreen();QPixmap pix = screen->grabWindow(0, x() + rectGif.x(), y() + rectGif.y(), rectGif.width(), rectGif.height());QImage image = pix.toImage().convertToFormat(QImage::Format_RGBA8888);gif.GifWriteFrame(gifWriter, image.bits(), rectGif.width(), rectGif.height(), fps); } //點擊開始錄制時,打開定時器觸發槽函數, void GifWidget::record() {if (btnStart->text() == "開始") {if (0 != gifWriter) {delete gifWriter;gifWriter = 0;}//確定gif文件的保存位置fileName = QFileDialog::getSaveFileName(this, "選擇保存位置", qApp->applicationDirPath() + "/", "gif圖片(*.gif)");if (fileName.isEmpty()) {return;}int width = txtWidth->text().toInt();int height = txtHeight->text().toInt();fps = txtFps->text().toInt();gifWriter = new Gif::GifWriter;bool bOk = gif.GifBegin(gifWriter, fileName.toLocal8Bit().data(), width, height, fps);if (!bOk) {delete gifWriter;gifWriter = 0;return;}count = 0;labStatus->setText("開始錄制...");btnStart->setText("停止");//延時啟動timer->setInterval(1000 / fps);QTimer::singleShot(1000, timer, SLOT(start()));} else {timer->stop();gif.GifEnd(gifWriter);delete gifWriter;gifWriter = 0;labStatus->setText(QString("錄制完成 共 %1 幀").arg(count));btnStart->setText("開始");QDesktopServices::openUrl(QUrl(fileName));} }其程序運行的結果如下圖所示:
總起來說,整個功能的實現分為兩步,第一是定時從桌面獲取截圖圖片,第二是將這些圖片按幀組合成gif文件。 程序的實現只是一種參考,希望對你有參考意義。
本文到此結束!
如果對你有幫助,請隨手 點贊 或 點喜歡!關注本專欄,更多干貨與你分享。
=======================================================
歡迎【關注、私信 @武三郎】。我們一起交流一起進步。
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的qt中实现左右分割线_Qt项目中,实现屏幕截图并生成gif的详细示例(值得细读)...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电脑卓大师怎么用(卓大师APP)
- 下一篇: tf调不到keras怎么 回事_格力变频