使用QtConcurrent使用QImageReader读取图像文件 [英] Read image files with QImageReader using QtConcurrent

查看:551
本文介绍了使用QtConcurrent使用QImageReader读取图像文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用QImageReader一次(每个图块)读取图像文件的一部分,以便对于非常大的图像,直到需要显示它们时才将它们从磁盘读取到内存中.

I am trying to use QImageReader to read portions of an image file at a time (per Tile), so that for very large images they are not read into memory from disk until they need to be displayed.

似乎我遇到了一些线程安全问题.

It seems liek I am running into some thread safety issues.

这是我目前拥有的:

#include "rastertile.h"

QMutex RasterTile::mutex;
RasterTile::RasterTile()
{
}

//RasterTile::RasterTile(QImageReader *reader, int nBlocksX, int nBlocksY, int xoffset, int yoffset, int nXBlockSize, int nYBlockSize)
RasterTile::RasterTile(QString filename, int nBlocksX, int nBlocksY, int xoffset, int yoffset, int nXBlockSize, int nYBlockSize)

    : Tile(nBlocksX, nBlocksY, xoffset, yoffset, nXBlockSize, nYBlockSize)
{
        this->reader = new QImageReader(filename);
        connect(&watcher,SIGNAL(finished()),this,SLOT(updateSceneSlot()));
}


void RasterTile::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget)
{
    if(image.isNull())
    {
        TilePainter=painter;
        TileOption=option;
        TileWidget=widget;
        future = QtConcurrent::run(this, &RasterTile::LoadTilePixmap);
        watcher.setFuture(future);

    }else
    {
        QRectF imageRect = image.rect();
        painter->drawImage(imageRect, image);
    }

}

QImage RasterTile::LoadTilePixmap()
{
    QMutexLocker locker(&mutex);

    QImage img(nBlockXSize, nBlockYSize, QImage::Format_RGB32);

    QRect rect(tilePosX*nBlockXSize, tilePosY*nBlockYSize, nBlockXSize, nBlockYSize);

    reader->setClipRect(rect);
    reader->read(&img);
    if(reader->error())
    {
        qDebug("Not null error");
        qDebug()<<"Error string is: "<<reader->errorString();
    }
    return img;

}

因此,这基本上是为每个图块实例化一个新的读取器,并更新超类的"image"变量,然后可以对其进行绘制.

So this is basically instantiating a new reader for each tile, and update the "image" variable of the superclass, which I can then paint.

这似乎给我带来了很多读者的错误,他们只是说无法读取图像数据"

This seems to give me a lot of errors from the reader, which simply say "Unable to read image data"

我认为这可能与许多访问同一文件的图块有关,但是我不知道如何证明或修复它.

I think this is probably something to do with many tiles accessing the same file, but I dont know how to prove that, or fix it.

我认为Qt使用libjpeg和libpng以及其他任何方式读取各种图像格式.

I think Qt uses libjpeg and libpng and whatever else to read various image formats.

推荐答案

我在这里看到两个潜在的问题.

I see two potential problems here.

  1. 这不是您的真正问题,但是以后会成为小瓷砖的问题.在线程启动后 设置future.如果在正确设置future之前线程完成了,这可能会引起麻烦. (对此不是100%的确定,但可以说... 85%,我相信这种情况极不可能发生)
  2. paint可以经常被调用.我相信您的问题是在读取线程完成之前第二次调用它.这将导致另一个线程在第一个仍在读取该图块时尝试读取该图块.您甚至会尝试同时使用相同的QImageReader实例...
  1. This is not your real problem but my be an issue with small tiles later. future is set after the thread is started. This may cause trouble, if the thread finishes, before future is set correctly. (Not 100% sure about this, but lets say... 85%, and I believe this is very unlikely to happen)
  2. paint can be called really often. I believe your problem is that it is called the second time, before your reading thread finished. This would cause another thread trying to read the tile while the first one is still reading it. Thy will even try to use the same instance of QImageReader at the same time...

这篇关于使用QtConcurrent使用QImageReader读取图像文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆