QQuickImageProvider 只加载大约 1% 的原始图像

QQuickImageProvider loads only around 1% of raw images

我开始学习 Qt,我想在带有缩略图的文件夹中制作简单的图像列表。我设法使其正常工作,但它似乎 运行domly 仅加载 500 张图像中的大约 1 张图像,50 张图像中的 1 张图像是黑色的(下面的屏幕截图)。一旦滚开,缩略图可能不会再次加载,这次可能会加载其他缩略图。对于原始图像,我使用 libraw。

少量观察:

7.7.2017 - 我试图检查问题是否是由损坏的文件引起的。虽然libraw说缩略图是jpg,但好像不是,因为普通浏览器无法浏览成功或失败的尝试,但更好的编辑器可以同时打开。所以看起来问题不在于将损坏的数据提供给 QImage

当我硬编码很少的照片来加载时,当照片较少时,它们几乎总能正确加载。随着数量的增加,它们突然都变黑或根本无法加载。也许是多线程问题?

Libraw 似乎总能正确加载文件。我通过在文件加载时和未加载时在文件中间打印足够的字节来测试它

当图像为黑色时,它认为一切都很好,当图像根本没有加载时,因为 QImage 有空内容。

当我多次添加一张图片时,所有副本的命运相同(它们都加载或全部失败)

QImage RawImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize) {
LibRaw rawProc;
auto state = rawProc.open_file(id.toLatin1().data());
QImage thumbnail;
if(LIBRAW_SUCCESS == state) {
    if(LIBRAW_SUCCESS == rawProc.unpack_thumb()) {
        if (LIBRAW_THUMBNAIL_JPEG == rawProc.imgdata.thumbnail.tformat) {
            thumbnail.loadFromData((unsigned char*)rawProc.imgdata.thumbnail.thumb, rawProc.imgdata.thumbnail.tlength, "JPEG");
        }
    }
    rawProc.recycle();
}
return thumbnail;
}

显示图像我使用 gridview 和 model-delegate

GridView {
    id: gridView
    anchors.rightMargin: 6
    anchors.leftMargin: 6
    anchors.bottomMargin: 6
    anchors.topMargin: 46
    anchors.fill: parent
    cellHeight: 200
    cellWidth: 185
    model: imageModel
    delegate: PhotoDelegate {}
}

raw image provider和model在main函数中是这样注册的

int main(int argc, char *argv[])
{
...
QQmlApplicationEngine engine;
engine.addImageProvider(QLatin1String("rawProvider"), new RawImageProvider);

AppData::setContext(engine.rootContext());
AppData::notifyContext();
...
}

AppData 是我的 "static" class,它包含创建模型的列表和指向上下文的指针,因此我可以轻松地从其他 class 访问和更新这些值来自 qml(文件浏览器)。每次数据更改时,模型更新如下。

void AppData::notifyContext() {
     context->setContextProperty("imageModel", QVariant::fromValue(dataList));
}

我真的 运行 不知道如何解决这个问题,任何帮助都会...嗯...有帮助

问题很简单。 Libraw 的 jpg 缩略图实际上只是 jpg 格式的原始图像(我不知道这一点,我的错)并且 QtQuick 无法处理它提供的图像大小。这就是为什么它在图像较少的情况下工作得很好,但在图像较多的情况下却非常失败。解决方案是将调整后的缩略图返回到更小的尺寸,理想情况下恰好是 qml 中图像的尺寸。

 return thumbnail.scaled(320, 320).scaled(160, 160, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);