Как сохранить QPixmap в JSON, через QByteArray?
у меня есть QByteArray
, который я хочу сохранить в файле JSON с помощью Qt, а также иметь возможность читать из него снова. Поскольку JSON изначально не может хранить необработанные данные, я думаю, что лучшим способом, вероятно, будет строка? Цель состоит в том, чтобы сохранить QPixmap таким образом:
{
"format" : "jpg",
"data" : "...jibberish..."
}
как этого достичь и как снова прочитать из этого объекта JSON (я использую Qt5)? То, что у меня сейчас есть, выглядит так:
QPixmap p;
...
QByteArray ba;
QBuffer buffer(&ba);
buffer.open(QIODevice::WriteOnly);
p.save(&buffer, "jpg");
QJsonObject json;
gameObject["data"] = QString(buffer.data());
QJsonDocument doc(json);
file.write(doc.toJson());
но полученный "jibberish" - это способ сократить, чтобы содержать целое изображение.
1 ответов
A QString
невозможно построить из произвольного QByteArray
. Вам нужно кодировать массив байтов так, чтобы он сначала конвертировался в строку. Это несколько вводит в заблуждение, что QString
является конструктивным из QByteArray
С точки зрения семантики C++. Является ли он действительно конструктивным, зависит от того, что находится в QByteArray
.
QByteArray::toBase64
и fromBase64
- это один из способов сделать это.
поскольку вы хотите сохранить pixmap без потери его содержимого, вы не следует сохранять его в формате с потерями, таком как JPG. Вместо этого используйте PNG. Используйте JPG только в том случае, если вы не загружаете и не сохраняете один и тот же pixmap при выполнении полной схемы JSON->pixmap->json.
есть еще один gotcha: для pixmap для хранения или загрузки, он должен внутренне преобразовать в/из QImage
. Это включает в себя потенциально преобразования цветового формата. Такие преобразования могут привести к потере данных. Вы должны быть осторожны, чтобы убедиться, что любые roundtrips сделаны с тем же формат.
в идеале, вы должны использовать QImage
вместо QPixmap
. В современном Qt a QPixmap
это просто тонкая обертка вокруг QImage
в любом случае.
// https://github.com/KubaO/stackoverflown/tree/master/questions/pixmap-to-json-32376119
#include <QtGui>
QJsonValue jsonValFromPixmap(const QPixmap &p) {
QBuffer buffer;
buffer.open(QIODevice::WriteOnly);
p.save(&buffer, "PNG");
auto const encoded = buffer.data().toBase64();
return {QLatin1String(encoded)};
}
QPixmap pixmapFrom(const QJsonValue &val) {
auto const encoded = val.toString().toLatin1();
QPixmap p;
p.loadFromData(QByteArray::fromBase64(encoded), "PNG");
return p;
}
int main(int argc, char **argv) {
QGuiApplication app{argc, argv};
QImage img{32, 32, QImage::Format_RGB32};
img.fill(Qt::red);
auto pix = QPixmap::fromImage(img);
auto val = jsonValFromPixmap(pix);
auto pix2 = pixmapFrom(val);
auto img2 = pix2.toImage();
Q_ASSERT(img == img2);
}