在Qt中实时保存

时间:2013-06-17 11:20:14

标签: c++ qt real-time

我在Qt中创建了一个应用程序,类似于scribble(在示例应用程序中给出)。目的是让用户徒手画画,一旦完成,将这些图纸上传到网上。截至目前,我每5秒将绘图保存为PNG图像,因此在意外关闭事件中数据丢失最小(我保持5秒以最小化写入操作;真正的实时非常需要) 。
但问题是,我每隔5秒将整个页面保存为图像,其中添加的新数据可能只有几个像素。我想知道我是否只能写入添加到磁盘中的新像素;保存时我不应该使用PNG;当用户说他已经完成时,我可以在最后将数据转换为PNG。

用于保存非常基本的代码;

void SaveData(const QString &fileName, const char *fileFormat, QImage image)
{
    mutex.lock();
    QImage visibleImage = image;

    if (visibleImage.save(fileName, fileFormat, 50)) 
    {
    system("sync");
    mutex.unlock();
    return true;

    } else {

    mutex.unlock();
        return false;

    }
}

我只是想知道真实实时保存是否可以添加像素......!

提前致谢

DK

4 个答案:

答案 0 :(得分:4)

我建议您使用图块来保存图像。将画布分成许多例如64x64矩形。并将每个矩形保存到单独的文件中。当某些内容发生变化时,您只需要重写几个小文件而不是重写整个图片。

您的代码中还有另一个危险的事情。当您运行QImage::save时,它很可能会删除文件内容并写入新内容。如果系统在两个操作之间关闭,则您的文件将变为空。因此,将新内容写入临时文件然后将其移动到正确的位置非常重要。保留几个旧版本的文件也很有用。谁知道文件系统在关机时会如何反应。

答案 1 :(得分:2)

您可以使用内存映射文件,例如:

    QFile file("rawimage.dat");
    file.open(QIODevice::ReadWrite);
    // Make sure there is enough memory for the image
    quint32 width = 16;
    quint32 height = 16;
    quint32 bpp32 = 4;
    qint64 file_size = width * height * bpp32;
    file.resize(file_size);
    uchar* mem = file.map(0, file_size);

    // make a QImage that uses the file as memory
    QImage img(mem, 16, 16, QImage::Format_ARGB32);
    // Do some drawing in the image
    img.fill(0);

    // finished with the file
    file.unmap(mem);
    file.close();

您需要检查它是否正确刷新到磁盘 - 我还没有测试过。理想情况下,在Windows上,您希望能够在内存映射句柄上调用“FlushViewOfFile”,以确保将已修改的页面写入磁盘。在Qt中看起来没有办法调用它,因此您可能需要在此处执行特定于操作系统的操作,以确保磁盘映像在您希望的情况下保持一致。

答案 2 :(得分:1)

您可以创建绘制项目的QPainterPath对象列表,然后将其呈现给QImage。您需要更改鼠标事件以执行以下操作: -

  • 鼠标按下:创建一个新的QPainterPath(painterPath)并调用painterPath-> moveTo
  • 鼠标移动:调用painterPath-> LineTo
  • 鼠标向上:将QPainterPath存储在列表中。

在paint事件中,然后传递每个要绘制的新QPainterPath

要备份,每隔n秒,打开一个文件并附加自上次保存列表以来的新QPainterPath流。

要恢复,请打开文件,将其重新流入并将其绘制到图像上。

这可以优化以检查新项目,如果不存在则不打扰保存。此外,您可以维护QPainterPath中创建的多个点,而不是基于时间,只有当它超过一定数量时才会保存。

请注意,如果你确实沿着这条路线走下去,你可能还想用每个QPainterPath存储Painter设置,如果用户也可以更改笔颜色,宽度等内容。

使用QPainterpath会带来其他好处 - 例如,用户可以打开一个图像然后再打开第二个图像,选择将其绘制在第一个图像之上。

答案 3 :(得分:0)

如果您想要实时保存,我建议您使用未压缩的位图格式。改变像素就像在文件内部寻找x-y坐标一样简单,通常计算为

file.seek(y * lineWidth + x * pixelDataSize);
file.write(pixelData);