Speed up document saving

If there are images need to be saved, such as the model turnaround reference sheet and texture images, the document saving may be slow because of image encoding to png, now, all the images are pre encoded when the first load, so the document saving could be speed up by avoid the cost of image encoding.
master
Jeremy Hu 2018-11-11 21:08:13 +08:00
parent dff8e40ef8
commit 39cfe6537d
5 changed files with 31 additions and 16 deletions

View File

@ -7,6 +7,7 @@
#include <QApplication>
#include <QVector3D>
#include <functional>
#include <QBuffer>
#include "document.h"
#include "util.h"
#include "snapshotxml.h"
@ -719,6 +720,10 @@ void Document::setNodeBoneMark(QUuid nodeId, BoneMark mark)
void Document::updateTurnaround(const QImage &image)
{
turnaround = image;
turnaroundPngByteArray.clear();
QBuffer pngBuffer(&turnaroundPngByteArray);
pngBuffer.open(QIODevice::WriteOnly);
turnaround.save(&pngBuffer, "PNG");
emit turnaroundChanged();
}

View File

@ -1102,13 +1102,8 @@ void DocumentWindow::saveTo(const QString &saveAsFilename)
if (modelXml.size() > 0)
ds3Writer.add("model.xml", "model", &modelXml);
QByteArray imageByteArray;
QBuffer pngBuffer(&imageByteArray);
if (!m_document->turnaround.isNull()) {
pngBuffer.open(QIODevice::WriteOnly);
m_document->turnaround.save(&pngBuffer, "PNG");
if (imageByteArray.size() > 0)
ds3Writer.add("canvas.png", "asset", &imageByteArray);
if (!m_document->turnaround.isNull() && m_document->turnaroundPngByteArray.size() > 0) {
ds3Writer.add("canvas.png", "asset", &m_document->turnaroundPngByteArray);
}
std::set<QUuid> imageIds;
@ -1133,15 +1128,11 @@ void DocumentWindow::saveTo(const QString &saveAsFilename)
}
for (const auto &imageId: imageIds) {
const QImage *image = ImageForever::get(imageId);
if (nullptr == image)
const QByteArray *pngByteArray = ImageForever::getPngByteArray(imageId);
if (nullptr == pngByteArray)
continue;
QByteArray imageByteArray;
QBuffer pngBuffer(&imageByteArray);
pngBuffer.open(QIODevice::WriteOnly);
image->save(&pngBuffer, "PNG");
if (imageByteArray.size() > 0)
ds3Writer.add("images/" + imageId.toString() + ".png", "asset", &imageByteArray);
if (pngByteArray->size() > 0)
ds3Writer.add("images/" + imageId.toString() + ".png", "asset", pngByteArray);
}
if (ds3Writer.save(filename)) {

View File

@ -1,12 +1,14 @@
#include <map>
#include <QMutex>
#include <QMutexLocker>
#include <QBuffer>
#include "imageforever.h"
struct ImageForeverItem
{
QImage *image;
QUuid id;
QByteArray *imageByteArray;
};
static std::map<QUuid, ImageForeverItem> g_foreverMap;
static std::map<qint64, QUuid> g_foreverCacheKeyToIdMap;
@ -21,6 +23,15 @@ const QImage *ImageForever::get(const QUuid &id)
return findResult->second.image;
}
const QByteArray *ImageForever::getPngByteArray(const QUuid &id)
{
QMutexLocker locker(&g_mapMutex);
auto findResult = g_foreverMap.find(id);
if (findResult == g_foreverMap.end())
return nullptr;
return findResult->second.imageByteArray;
}
QUuid ImageForever::add(const QImage *image, QUuid toId)
{
QMutexLocker locker(&g_mapMutex);
@ -35,7 +46,11 @@ QUuid ImageForever::add(const QImage *image, QUuid toId)
if (g_foreverMap.find(newId) != g_foreverMap.end())
return newId;
QImage *newImage = new QImage(*image);
g_foreverMap[newId] = {newImage, newId};
QByteArray *imageByteArray = new QByteArray();
QBuffer pngBuffer(imageByteArray);
pngBuffer.open(QIODevice::WriteOnly);
newImage->save(&pngBuffer, "PNG");
g_foreverMap[newId] = {newImage, newId, imageByteArray};
g_foreverCacheKeyToIdMap[newImage->cacheKey()] = newId;
return newId;
}

View File

@ -2,11 +2,13 @@
#define DUST3D_IMAGE_FOREVER_H
#include <QImage>
#include <QUuid>
#include <QByteArray>
class ImageForever
{
public:
static const QImage *get(const QUuid &id);
static const QByteArray *getPngByteArray(const QUuid &id);
static QUuid add(const QImage *image, QUuid toId=QUuid());
};

View File

@ -5,6 +5,7 @@
#include <QString>
#include <cmath>
#include <QImage>
#include <QByteArray>
#include "bonemark.h"
#include "theme.h"
#include "meshloader.h"
@ -200,6 +201,7 @@ public:
bool zlocked = false;
bool radiusLocked = false;
QImage turnaround;
QByteArray turnaroundPngByteArray;
std::map<QUuid, SkeletonPart> partMap;
std::map<QUuid, SkeletonNode> nodeMap;
std::map<QUuid, SkeletonEdge> edgeMap;