UPD 。好的,因为我的问题大多引起困惑,所以我将尝试通过将问题缩小到要点来解决问题。
给出:
几GB的大图像,称为img.jpg
(.png
/ .bmp
);
图像rect = QRect(x,y,w,h)
上小片段的坐标;
写:
rect
从磁盘上的映像加载到QPixmap
的函数;该函数将被频繁调用。尝试的解决方案和问题:
QImageReader
的{{1}}在图像上指定要加载的区域。完美吧?好吧,问题在于方法setClipRect(QRect)
仅在第一次调用时才返回read()
。之后,它将返回带有错误消息“无法读取图像数据”的空图像。将QImage
所使用的QIOReader
倒退为零无济于事。再次创建QImageReader
会大大提高性能。链接:
QImageReader
来倒回QIODevice。问题是它不起作用:倒退设备reader->device()->seek(0);
后仍然返回空的reader->read()
并产生错误消息“无法读取图像数据”。下面是带有更多详细信息的原始帖子。
我正在编写一个小部件,该小部件可部分加载图像并将其显示在QImage
中,并带有可根据其在视口中的可见性加载和卸载的图块。磁贴在卸载时会显示一个占位符,并根据需要将相应的片段加载到QGraphicsScene
中。该小部件应该能够在不占用大量内存的情况下打开大小高达数GB的图像。
我打算让每个图块都打开图像,并准备从特定位置读取。我正在使用QPixmap
,它允许您设置一个矩形来定义要加载的图像区域。但是事实证明,设置矩形后,我只能一次读取图像。为了再次加载它,我必须创建一个QImageReader
的新实例,它将打开文件 anew 。我尝试用256x256瓦片打开〜2Gb图像,并且加载速度非常慢:在我的计算机上,加载一个高清屏幕大约需要30秒。
这是我当前用于加载图块的代码:
QImageReader
我不是每次都创建void TileLoader::load(int posx, int posy, int w, int h, QString filename) {
QImageReader reader(filename);
QRect tile(posx, posy, w, h);
reader.setClipRect(tile);
QImage image(w, h, QImage::Format_RGB32);
reader.read(&image);
emit tileLoaded(QPixmap::fromImage(image));
}
实例,而是希望将现有实例作为参数传递。但不幸的是,它只能运行一次,因此QImageReader
并非可行之路。但是什么呢?
如果将图块大小设置为16x16,我还可以使用约1000x1000像素的常规图像重新创建缓慢加载。我可以看到小块瓷砖以波浪状的动作展现在我眼前的图像,持续了约10秒钟,这是一件很漂亮的事情,但就眼前的任务而言却是完全不切实际的。
所以问题是:有没有办法在图块存在的整个过程中保持我的图像文件处于打开状态,以便它可以快速读取其中的一部分?