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

时间:2017-07-06 14:22:15

标签: qt qtquick2 qtquickcontrols2

我开始学习Qt,我想用缩略图在文件夹中制作简单的图像列表。我设法让它有点工作,但它似乎随机加载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 {}
}

原始图像提供者和模型在主要功能中如此注册

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

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

AppData是我的“静态”类,它包含创建模型的列表和上下文指针,因此我可以从qml(文件浏览器)调用的其他类中轻松访问和更新这些值。每次更改数据时都会按照以下步骤更新模型。

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

我真的没有想法如何解决这个问题,任何帮助都会......嗯......乐于助人

this is how it looks

1 个答案:

答案 0 :(得分:1)

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

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