QMovie webp рамка заикается - PullRequest
0 голосов
/ 26 ноября 2018

Я использую QMovie для воспроизведения веб-анимации на QLabal, код такой как:

Foo::Foo() {
    movie_ = new QMovie("/path/to/my.webp", "", this);
    ui->label->setMovie(movie_);
}
void Foo::on_pushButton_clicked() {
    movie_->stop();
    movie_->start();
}

Но когда я играю анимацию, кадр заикается, например:

the screenshot

Я пытаюсь извлечь кадры webp с помощью QImage :: save, код такой:

QImageReader *reader = new QImageReader("/path/to/my.webp");
reader->setDecideFormatFromContent(true);
for (int i = 0; i < reader->imageCount(); ++i) {
    QImage image;
    reader->read(&image);
    image.save(QString("frame_%1.png").arg(i));
    reader->jumpToNextImage();
}

все извлеченные кадры тоже заикаются, как:

frame_9.png

Но когда я извлекаю кадры с помощью google libwebp tool, проблем не возникает. Like:

frame_9_2.png

// extract frame 9, not problem
webpmux.exe -get frame 9  -o "frame_9.webp"
// paly webp animation, there is no any problem
vwebp.exe /path/to/my.webp

Является ли этоQt проблема?Qt 5.9.4 (я использую) и последняя версия Qt (я пытаюсь) имеет эту проблему.

1 Ответ

0 голосов
/ 27 ноября 2018

Кажется, ошибка Qt, ошибка сообщается в Qt версии 5.9.1: WebP: анимации не учитывают альфа

Qt говорит, что ошибка была решена в версии 5.9.2, но проблемы все еще существуют, даже в Qt 5.11.

есть официальное решение :

diff --git a/src/plugins/imageformats/webp/qwebphandler.cpp b/src/plugins/imageformats/webp/qwebphandler.cpp
index 5a0ae4a..ce90158 100644
--- a/src/plugins/imageformats/webp/qwebphandler.cpp
+++ b/src/plugins/imageformats/webp/qwebphandler.cpp
@@ -122,6 +122,8 @@ bool QWebpHandler::ensureScanned() const
                 that->m_bgColor = QColor::fromRgba(QRgb(WebPDemuxGetI(m_demuxer, WEBP_FF_BACKGROUND_COLOR)));

                 that->m_composited = new QImage(that->m_features.width, that->m_features.height, QImage::Format_ARGB32);
+                if (that->m_features.has_alpha)
+                    that->m_composited->fill(Qt::transparent);

                 // We do not reset device position since we have read in all data
                 m_scanState = ScanSuccess;
@@ -193,6 +195,8 @@ bool QWebpHandler::read(QImage *image)
     } else {
         // Animation
         QPainter painter(m_composited);
+        if (m_features.has_alpha && m_iter.dispose_method == WEBP_MUX_DISPOSE_BACKGROUND)
+            m_composited->fill(Qt::transparent);
         painter.drawImage(currentImageRect(), frame);

         *image = *m_composited;

Вот мое решение:

1.Добавьте код

// ${QT_SRC}/qtimageformats/src/plugins/imageformats/webp/qwebphandler.cpp
// function QWebpHandler::read
if (m_features.has_alpha && (m_iter.dispose_method == WEBP_MUX_DISPOSE_BACKGROUND || 
            m_iter.blend_method == WEBP_MUX_NO_BLEND)) {
      m_composited->fill(Qt::transparent);
}

2.пересобрать плагин qt webp

nmake module-qtimageformats

заменить qwebp.dll

mv ${QT_DIR}/plugins/imageformats/qwebpd.dll ${QT_DIR}/plugins/imageformats/qwebpd.dll.bak

cp ${REBUILD_WEBP_PLUGINS} ${QT_DIR}/plugins/imageformats/qwebpd.dll

...