Reputation: 1
I have never coded with C++ nor with Qt, but I wanted to customize Flameshot to upload images to my self-hosted Picsur instance. However, Picsur uses a different method for uploading images via api than Imgur to which Flameshot uploads originally.
I did figure out how to make the http request and I have code that works completely, but my problem is, that in order to make it work I have to save the QPixmap to a file and then upload that file which works but is not really efficient.
What I tried before saving and then uploading the file is to just use the QBuffer directly as the body device for the http request, but when I executed that I would get this error in my console: 18344 Segmentation fault (core dumped)
. I wasn't able to find any other errors, including with setting the variable QT_LOGGING_RULES
to "*.debug=true"
.
Here's my functioning code that works by saving the file:
QByteArray byteArray;
QBuffer buffer(&byteArray);
buffer.open(QIODevice::WriteOnly);
pixmap().save(&buffer, "PNG");
buffer.close();
QSaveFile saveFile("tmp.png");
saveFile.open(QIODevice::WriteOnly);
saveFile.write(byteArray);
saveFile.commit();
QFile *file = new QFile("tmp.png");
file->open(QIODevice::ReadOnly);
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart filePart;
filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"image\"; filename=\"" + FileNameHandler().parsedPattern() + "\""));
filePart.setBodyDevice(file);
file->setParent(multiPart);
multiPart->append(filePart);
QUrl url(QStringLiteral("https://example.org/api/image/upload"));
QNetworkRequest request(url);
request.setRawHeader("Authorization",
QStringLiteral("Api-Key %1")
.arg(ConfigHandler().uploadClientSecret())
.toUtf8());
m_NetworkAM->post(request, multiPart);
Here's the code that throws the segmentation error:
QByteArray byteArray;
QBuffer *buffer = new QBuffer(&byteArray);
buffer->open(QIODevice::WriteOnly);
pixmap().save(buffer, "PNG");
buffer->seek(0);
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart filePart;
filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"image\"; filename=\"" + FileNameHandler().parsedPattern() + "\""));
filePart.setBodyDevice(buffer);
multiPart->append(filePart);
QUrl url(QStringLiteral("https://example.org/api/image/upload"));
QNetworkRequest request(url);
request.setRawHeader("Authorization",
QStringLiteral("Api-Key %1")
.arg(ConfigHandler().uploadClientSecret())
.toUtf8());
m_NetworkAM->post(request, multiPart);
The function pixmap()
returns the QPixmap which holds the image data from the screenshot Flameshot took. m_NetworkAM
is a variable from the class defined as such:
m_NetworkAM = new QNetworkAccessManager(this);
connect(m_NetworkAM,
&QNetworkAccessManager::finished,
this,
&ImgurUploader::handleUpload);
For the sake of completeness, here's the original code from Flameshot:
QByteArray byteArray;
QBuffer buffer(&byteArray);
pixmap().save(&buffer, "PNG");
QUrlQuery urlQuery;
urlQuery.addQueryItem(QStringLiteral("title"), QStringLiteral(""));
QString description = FileNameHandler().parsedPattern();
urlQuery.addQueryItem(QStringLiteral("description"), description);
QUrl url(QStringLiteral("https://api.imgur.com/3/image"));
url.setQuery(urlQuery);
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader,
"application/application/x-www-form-urlencoded");
request.setRawHeader("Authorization",
QStringLiteral("Client-ID %1")
.arg(ConfigHandler().uploadClientSecret())
.toUtf8());
m_NetworkAM->post(request, byteArray);
The whole file is viewable here: imguruploader.cpp
As I said, I'm completely new to C++ as well as Qt, so it could totally be possible that I made a completely obvious mistake here.
Upvotes: -1
Views: 108
Reputation: 1
I solved this now using the QByteArray
directly via the function setBody
. Many thanks to @IgorTandetnik for pointing that out!
This is the functioning code:
QByteArray byteArray;
QBuffer buffer(&byteArray);
buffer.open(QIODevice::WriteOnly);
pixmap().save(&buffer, "PNG");
buffer.close();
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart filePart;
filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"image\"; filename=\"" + FileNameHandler().parsedPattern() + "\""));
filePart.setBody(byteArray);
multiPart->append(filePart);
QUrl url(QStringLiteral("https://example.org/api/image/upload"));
QNetworkRequest request(url);
request.setRawHeader("Authorization",
QStringLiteral("Api-Key %1")
.arg(ConfigHandler().uploadClientSecret())
.toUtf8());
m_NetworkAM->post(request, multiPart);
Upvotes: 0