【问题标题】:Having difficulty in storing a QImage and then recovering it难以存储 QImage 然后恢复它
【发布时间】:2010-06-25 16:51:55
【问题描述】:

好吧,我正在尝试在许多图像绘制程序中实现类似于“撤消”功能的东西。我遇到的问题是:我正在尝试在 QVector 中制作 QImage 对象的备份副本(最多存储 10 个最新的 QImage 副本用于备份),然后尝试在另一个函数中检索这些备份。问题是没有正确创建备份(因为当我尝试恢复备份的映像时,没有任何反应)。我知道问题出在备份部分而不是恢复部分,因为当我备份具有红色背景的新临时图像时,它可以完美恢复..

这是备份功能代码:

imageBackups.append(image);

'image' 是我要备份的 QImage 对象..

这是备用备份(存储红色背景图像) - 我使用它只是为了查看此版本的备份是否有效,它确实有效:

QImage newImage(QSize(100,100), QImage::Format_RGB32);
newImage.fill(qRgb(255, 0, 0));
imageBackups.append(newImage);

这里是恢复代码:

image =imageBackups.at(imageBackups.size()-1);
QPainter painter(&image);
painter.drawImage(QPoint(0,0),imageBackups.at(imageBackups.size()-1));

'image' 的定义与上面的 newImage 完全相同,只是在这种情况下大小为 800x400..

【问题讨论】:

  • QVector 可能不是存储备份图像的最佳数据结构。 QList 或 QQueue 可能更适合这种用途。

标签: c++ qt


【解决方案1】:

newImage 在超出范围时开始被析构,我猜追加正在做某种浅拷贝,它只存储对图像的引用。 QT 对某些对象进行自动引用计数,但我不记得细节了

尝试使用 new 创建 QImage 并将指针存储在 imageBackups 中(无论如何都是更好的方法)。

类似这样的东西(注意 imageBackups 现在需要是 QIMage* 的数组)

QImage pImage = new QImage(QSize(100,100), QImage::Format_RGB32);
pImage->fill(qRgb(255, 0, 0));
imageBackups.append(pImage);

【讨论】:

  • 你说我应该为上面的哪个代码使用 new ?当你写 QImage newImage ( ... ); ,你不是在创建一个新的 QImage 对象吗?另外,在附加过程中,我看不到任何可以提及新的地方..
  • 好吧,关于浅拷贝的事情你是对的。如果我将第二个备份代码更改为:QImage newImage(QSize(100,100), QImage::Format_RGB32); newImage.fill(qRgb(255, 0, 0)); imageBackups.append(newImage); newImage.~QImage();恢复不起作用......但是我通过使用这个来解决这个问题: QImage newImage(QSize(100,100), QImage::Format_RGB32); newImage.fill(qRgb(255, 0, 0)); imageBackups.append(newImage.copy(QRect())); newImage.~QImage();但原来的问题仍然存在......
【解决方案2】:

这可能与您创建图像的方式有关。如果您使用采用uchar * 缓冲区(或不const)的构造函数之一,则必须确保缓冲区在QImage 及其副本的整个生命周期内都是有效的:

http://doc.trolltech.com/latest/qimage.html#QImage-5

如果在您从QVector 恢复图像时,缓冲区被删除,则恢复的QImage 将使用一些陈旧的内存位置作为缓冲区。

【讨论】:

    【解决方案3】:

    我认为您的恢复代码可能有问题。从您的实际代码转移到问题时,也许这只是一个错字,但您应该调查一下。这是我解析恢复代码的方法。

    // Get the image that is back one.
    image =imageBackups.at(imageBackups.size()-1);
    // Create a painter onto the backup image
    QPainter painter(&image);
    // Paint the backup image in the painter (onto the backup image).
    painter.drawImage(QPoint(0,0),imageBackups.at(imageBackups.size()-1));
    

    我看不出这是如何完成任何事情的,这也许可以解释为什么在您恢复时似乎什么都没有发生。

    【讨论】:

      猜你喜欢
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-10
      • 1970-01-01
      • 2017-06-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多