How to store a QPixmap in JSON, via QByteArray? How to store a QPixmap in JSON, via QByteArray? json json

How to store a QPixmap in JSON, via QByteArray?


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