How to store a QPixmap in JSON, via QByteArray?

喜夏-厌秋 提交于 2020-07-29 05:43:00

问题


I have a QByteArray, which I want to save in a JSON file using Qt and also be able to read from it again. Since JSON natively can't store raw data, I think the best way would probably be a string? The goal is to save a QPixmap this way:

{
  "format" : "jpg",
  "data" : "...jibberish..."
}

How do I achieve this and how do I read from this JSON Object again (I am using Qt5)? What I have right now looks this way:

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());

But the resulting 'jibberish' is way to short to contain the whole image.


回答1:


A QString cannot be constructed from an arbitrary QByteArray. You need to encode the byte array such that it is convertible to a string first. It is somewhat misleading that a QString is constructible from a QByteArray from the C++ semantics point of view. Whether it is really constructible depends on what's in the QByteArray.

QByteArray::toBase64 and fromBase64 are one way of doing it.

Since you would want to save the pixmap without losing its contents, you should not save it in a lossy format like JPG. Use PNG instead. Only use JPG if you're not repeatedly loading and storing the same pixmap while doing the full json->pixmap->json circuit.

There's another gotcha: for a pixmap to store or load itself, it needs to internally convert to/from QImage. This involves potentially color format conversions. Such conversions may lose data. You have to be careful to ensure that any roundtrips are made with the same format.

Ideally, you should be using QImage instead of a QPixmap. In modern Qt, a QPixmap is just a thin wrapper around a QImage anyway.

// 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);
}


来源:https://stackoverflow.com/questions/32376119/how-to-store-a-qpixmap-in-json-via-qbytearray

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!