sle*_*nja 8 c++ qt image qt4 qgraphicsview
我正在创建一个在Qt中打开大图像(2gb +)的图像可视化工具.我是通过将大图像分成几个512X512的图块来做到这一点的.然后我加载原始图像大小的QGraphicsScene并使用addPixmap将每个图块添加到QGraphic场景上.所以最终它看起来像是一个巨大的图像给最终用户,实际上它是一个连续阵列的小图像粘在一起的场景.首先,这是一个好方法吗?
尝试将所有图块加载到场景中会占用大量内存.所以我想只加载视图中可见的图块.我已经设法将QGraphicsScene子类化并覆盖其拖动事件,从而使我能够根据移动知道接下来需要加载哪些切片.我的问题是跟踪滚动条上的移动.有没有什么办法可以创建一个每次滚动条移动时调用的事件.不能选择QGraphicsView的子类.
QGraphicsScene 足够聪明,不能渲染不可见的东西,所以这就是你需要做的:
不是加载和添加像素图,而是添加包装像素图的类,并且只在首次渲染时加载它.(计算机科学家喜欢称之为"代理模式").然后,您可以根据计时器卸载像素图.(如果过早卸载,它们将被透明地重新加载.)您甚至可以通知当前缩放级别的此代理路径,以便在它们渲染得更小时加载较低分辨率的图像.
编辑:这里有一些代码可以帮助您入门.请注意,QGraphicsScene绘制的所有内容都是a QGraphicsItem(如果你调用::addPixmap它,它会转换为...GraphicsItem幕后的),那么这就是你想要的子类:
(我甚至没有编译这个,所以"告诫lector",但它正在做正确的事;)
class MyPixmap: public QGraphicsItem{
public:
// make sure to set `item` to nullptr in the constructor
MyPixmap()
: QGraphicsItem(...), item(nullptr){
}
// you will need to add a destructor
// (and probably a copy constructor and assignment operator)
QRectF boundingRect() const{
// return the size
return QRectF( ... );
}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget){
if(nullptr == item){
// load item:
item = new QGraphicsPixmapItem( ... );
}
item->paint(painter, option, widget);
}
private:
// you'll probably want to store information about where you're
// going to load the pixmap from, too
QGraphicsPixmapItem *item;
};
Run Code Online (Sandbox Code Playgroud)
然后你可以添加你的pixmaps到QGraphicsScene使用QGraphicsScene::addItem(...)
虽然已经选择了答案,但我想表达我的意见.
我不喜欢所选择的答案,特别是因为使用了计时器.卸载pixmaps的计时器?假设用户实际上想要好好看看图像,几秒钟后--Bam,图像被卸载,他将不得不做一些事情以便图像重新出现.或者你可能会放另一个计时器,在几秒钟之后加载pixmaps?或者,如果可见,您将检查您的数千件物品?这不仅非常令人烦恼和错误,而且这意味着您的程序将始终使用资源.假设用户最小化您的节目并播放电影,他会想知道为什么我的电影每隔几秒就会冻结......
好吧,如果我误解了使用计时器的提议,请执行我.
实际上mmutz建议的想法更好.它让我想起了Mandelbrot的例子.看看吧.您可以重写此部分以加载您需要显示的图像部分,而不是计算要绘制的内容.
总之,我将以更简单的方式使用QGraphicsView提出另一种解决方案:
1)检查图像的大小而不加载图像(使用QImageReader)
2)使场景的大小等于图像的大小
3)而不是使用pixmap项重新实现DrawBackground()函数.其中一个参数将为您提供新的外露矩形 - 这意味着如果用户只滚动一点,您将只加载和绘制这个新部分(仅加载部分图像使用setClipRect()然后读取()方法的QImageReader类).如果有一些转换,您可以从其他参数(即QPainter)获取它们,并在绘制之前将它们应用于图像.
在我看来,最好的解决方案是将我的解决方案与Mandelbrot示例中显示的线程相结合.
我现在能想到的唯一问题是用户是否缩小了比例因子.然后,您需要一些时间来加载和扩展巨大的图像.好吧,我现在看到有一些QImageReader的功能,我还没有尝试过 - setScaledSize(),这可能正是我们需要的 - 如果你设置一个比例大小然后加载图像可能它不会先加载整个形象 - 尝试一下.另一种方法是限制比例因子,如果你坚持使用pixmap项目的方法,你应该做的事情.
希望这可以帮助.