[問題] QMovie 不吃 QZipReader 的fileData

看板C_and_CPP (C/C++)作者 (薯)時間3年前 (2021/02/25 01:43), 3年前編輯推噓2(207)
留言9則, 3人參與, 3年前最新討論串1/1
我的開發平台是 win7 工具是QT Creator 版本是Qt Core 5.15.2 我採用內建的 QZipReader (#include "private/qzipreader_p.h") 來讀取zip壓縮檔內的單一檔案,然後顯示 當讀取壓縮檔內的bmp, png, jpg時 我用QImage來讀取圖片可成功讀取 mPath = "F:/image/myzip.zip"; path = "myzip.zip/01.jpg"; mZipReader = new QZipReader(mPath); QByteArray data{mZipReader->fileData(path)}; bool isSuccessed = image.loadFromData(data,"JPG"); 但是如果要讀取的檔案是GIF檔 則無論用QImageReader 或是 QMovie 都無法成功讀取 mPath = "F:/image/myzip.zip"; path = "myzip.zip/1445806472.gif"; mZipReader = new QZipReader(mPath); QByteArray data{mZipReader->fileData(path)}; QMovie *movie = new QMovie(data, "GIF"); qDebug() << movie->isValid(); //false qDebug() << movie->lastErrorString(); //"File not found" qDebug() << movie->fileName(); // "GIF89a\u0016\u0002B\u0001?" 想請問除了換用其他的lib之外,還有其他讀取壓縮檔內gif可行的辦法嗎? 感謝閱讀 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 123.192.225.144 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1614188583.A.0E9.html

02/25 09:40, 3年前 , 1F
QMovie是要給IODevice
02/25 09:40, 1F

02/25 09:44, 3年前 , 2F
感謝大大的回覆 不過我發現使用QBuffer會產生Runtime的問題 https://imgur.com/P2ZV6SY
#include "mainwindow.h" #include "ui_mainwindow.h" #include "private/qzipreader_p.h" #include <QBuffer> #include <QMovie> #include <QLabel> #include<QByteArray> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); QZipReader *zip = new QZipReader("MMM.zip"); QByteArray ba{zip->fileData("1445806472.gif")}; QBuffer buff; buff.setData(ba); if(buff.open(QIODevice::ReadOnly)) qDebug() << "yes" ; QMovie *movie = new QMovie(&buff,"GIF"); ui->label->setMovie(movie); movie->start(); } MainWindow::~MainWindow() { delete ui; } qDebug() << "movie->fileName(): " << movie->fileName() ; //ok, 但是是空字串: "" qDebug() << "movie->isValid(): " << movie->isValid() ; //如果呼叫 movie->start() 為true //如未呼叫 movie->start() 會crash qDebug() << "movie->cacheMode(): " << movie->cacheMode(); //ok, QMovie::CacheNone qDebug() << "movie->currentFrameNumber(): " << movie->currentFrameNumber(); //ok, 0 qDebug() << "movie->device(): " << movie->device(); //ok, QObject(0x22ac50) qDebug() << "movie->format(): " << movie->format(); //ok, "GIF" qDebug() << "movie: " << movie->frameCount(); //crash qDebug() << "movie->loopCount(): " << movie->loopCount(); //crash qDebug() << "movie->nextFrameDelay(): " << movie->nextFrameDelay(); //crash 這是我測試的一個專案 QMoive基本上可以讀gif的第一張圖,然後程式就會crash 專案 https://mega.nz/file/B4lXXQJC#1oNPtQE8yAminrXsMfby1tBzMyQW8eka_aGUOhiMkp4 測試檔案 https://mega.nz/file/V00hUQpa#MzBDmO0nEtJ_JyuwCb78tpc0JXjlLbMOMTfAl1q3t3s

02/25 10:08, 3年前 , 3F
還有你的path是不是錯了,我用Qt 5.15.1要打"01.jpg"
02/25 10:08, 3F

02/25 10:09, 3年前 , 4F
才能讀檔,不是"myzip.zip/01.jpg",不過有可能是行為
02/25 10:09, 4F

02/25 10:09, 3年前 , 5F
變更
02/25 10:09, 5F
我是用QZipReader本身的api 來擷取zip檔內的file path的 foreach(QZipReader::FileInfo item, mZipReader->fileInfoList()){ if (item.isFile){ if (item.filePath.endsWith("jpg", Qt::CaseInsensitive) || item.filePath.endsWith("png", Qt::CaseInsensitive) || item.filePath.endsWith("gif", Qt::CaseInsensitive) || item.filePath.endsWith("bmp", Qt::CaseInsensitive)) mInfoList.enqueue(item.filePath); //QQueue<QString> } } ※ 編輯: liu2007 (123.192.225.144 臺灣), 02/25/2021 15:46:27 ※ 編輯: liu2007 (123.192.225.144 臺灣), 02/25/2021 15:47:14 ※ 編輯: liu2007 (123.192.225.144 臺灣), 02/25/2021 15:51:37 ※ 編輯: liu2007 (123.192.225.144 臺灣), 02/25/2021 16:19:04

02/25 16:24, 3年前 , 6F
看了你的程式碼,問題出在 QByteArray 和 QBuffer 物件
02/25 16:24, 6F

02/25 16:24, 3年前 , 7F
都是區域變數,當建構式一結束這兩個物件就銷毀了。
02/25 16:24, 7F

02/25 16:25, 3年前 , 8F
所以 movie->start() 才會 crash。
02/25 16:25, 8F

02/25 16:25, 3年前 , 9F
在 movie 播放 GIF 期間,這兩個物件都必須活著才行。
02/25 16:25, 9F
沒想到我犯了這種錯誤..... 感謝P大提點 ※ 編輯: liu2007 (123.192.225.144 臺灣), 02/25/2021 22:41:31
文章代碼(AID): #1WDf0d3f (C_and_CPP)
文章代碼(AID): #1WDf0d3f (C_and_CPP)