How to save a QPixmap Object to a file? - qt

I'm having trouble reading and writing QByteArray data to a file.
My goal is to save QPixmap data into a QByteArray and save that QByteArray to a file (with the ability to read this QByteArray back from the file and into a QPixmap). I want to use following code from the QPixmap documentation:
QPixmap pixmap(<image path>);
QByteArray bytes;
QBuffer buffer(&bytes);
buffer.open(QIODevice::WriteOnly);
pixmap.save(&buffer, "PNG"); // writes pixmap into bytes in PNG format
After writing the buffer to a file, I want to be able to retrieve the QByteArray and load it back into a QPixmap using the QPixmap::loadFromData() function.
Please let me know if any further clarification is needed (I'm open to alternative approaches as well, I just need to be able to read and write the QPixmap to a file! :) );

That seemed like a really long way to go about doing it (but your comment better explains):
For writing:
QFile file("yourFile.png");
file.open(QIODevice::WriteOnly);
pixmap.save(&file, "PNG");
For reading:
QPixmap pixmap;
pixmap.load("yourFile.png");
QBuffer is great when you need a QIODevice and want to keep it in memory, but if you're actually going out to disk, then it's an unnecessary middle step.
EDIT:
To write pixmaps, and other things, to a single file I'd recommend that you use QDataStream.
For writing:
QFile file("outfile.dat");
file.open(QIODevice::WriteOnly);
QDataStream out(&file);
out << QString("almost any qt value object")
<< yourQPixMap << yourQList /* << etc. */;
Then, you can do similarly for reading:
QFile file("infile.dat");
file.open(QIODevice::ReadOnly);
QDataStream in(&file);
in >> firstQString >> yourQPixmap >> yourList /* >> etc. */;
You'll need to make sure that you read in the same objects as you wrote them out. In order to save yourself future compatibility headaches, set the QDataStream version explicitly.

Related

Qt print document to PDF

I cannot print a QTextDocument to pdf. What I basically want is to print a table of data as a cell into a pdf file. The program runs on a virtual windows server. So I tried this:
Q_INVOKABLE QString ScriptCallback::htmlToPdf(const QString& sHtml) {
qDebug() << "Html To Pdf";
QPdfWriter pdfWriter("c:\\test.pdf");
pdfWriter.setPageSize(QPagedPaintDevice::A4);
pdfWriter.setPageMargins(QMargins(30, 30, 30, 30));
QTextDocument document;
document.setHtml(sHtml);
document.print(&pdfWriter);
QString s = "";
return s;
}
In fact instead of printing to the testfile I want to print to a QBuffer -> QByteArray. But this one above is for testing.
The problem is, I always get the error
QPainter::begin() failed
In Debug Mode the program continues, but in release the program even crashes trying to run the command
document.print(&pdfWriter);
I don't care about using QTextdocument or QPdfWriter. The only thing I am interessted in, is taking a bunch of data and somehow generate a table in a pdf file.
By the way the program runs as a console app (QCoreApplication). But I included gui and printsupport modules. So any alternatives are welcome as well.

Writing Issues With QTextStream

QFile vfile(file);
if(!vfile.open(QIODevice::ReadWrite | QIODevice::Text)) qDebug() << "FILE COULDN NOT BE OPENED";
QTextStream stream(&vfile);
stream << "Hello" << "=";
vfile.write("132");
Output to File - 132Hello=
In the above example, I write the data in 2 different ways but when I see the file I found some this type of result that while using "write()" the data within write() printed first instead of the above statements is displayed in the example.
The stream data is cached for a time (which is typical of writing to streams in general, eg. stdout and such). You can flush the stream data to be sure it is all written before writing to the file via a different method.
stream << "Hello=" << flush;
vfile.write("123");
Also see manipulator functions list in https://doc.qt.io/qt-5/qtextstream.html#details
Writing an end-of-line character (endln or \n) will also flush the stream buffer.

Qt Set image to label reference variable

I have some pictures in the resource file and their file names correspond to their staffIds. this is how I set the picture into my QLabel but nothing is shown.
QString staffId;
staffId=ui->lineEdit_staffID->text();
QPixmap managerPic(":/staff/\'"+staffId+"\'.jpg");
managerInterface.ui->label_mpic->setScaledContents(true);
managerInterface.ui->label_mpic->setPixmap(managerPic);
I'm with #Mike here, most probably the single quotes aren't part of your filenames. You can use the debugger to see what is passed to the QPixmap constructor, or put the name into a separate QString variable and write it to qDebug() to see what it contains.
In general you better use QString::arg() to build strings instead of concatenation; usually it's easier to read and understand:
QPixmap managerPic(QString(":/staff/\'%1\'.jpg").arg(staffId));
QPixmap managerPic(QString(":/staff/%1.jpg").arg(staffId));

Qt's QDir: File Names Dropping Non-Ascii Characters

I am having issues with QDir losing Non-Ascii characters from my file names.
I have files with names like testingöäüß.txt or exampleΦ.shp and when trying to use Qt utilities like QDir and QFile they simply show up as testing.txt and example.shp. Seems as though I cannot tell those classes what kind of encoding to use. I'm trying QDirIterator and the QDir function entryInfoList:
QDir someDir("/home/blah"); //contains testingöäüß.txt
QDirIterator dirIter(someDir.absolutePath(), QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files);
while(dirIter.hasNext())
{
QString fileName1 = QFile::decodeName(dirIter.next().toUtf8());
std::cout << "QDirIterator Name " << fileName1.toStdString().c_str() << std::endl;
}
QFileInfoList fileInfoList = someDir.entryInfoList(QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files);
foreach(QFileInfo fileInfo, fileInfoList)
{
QString fileName1 = QFile::decodeName(fileInfo.fileName().toUtf8());
std::cout << "entryInfoList Name " << fileName1.toStdString().c_str() << std::endl;
QString fileName2 = QFile::decodeName(fileInfo.absoluteFilePath().toUtf8());
std::cout << "entryInfoList Name2 " << fileName2.toStdString().c_str() << std::endl;
QString fileName3 = QString::fromUtf8(dirIter.fileInfo().absoluteFilePath().toStdString().c_str());
std::cout << "entryInfoList Name3 " << fileName3.toStdString().c_str() << std::endl;
}
Every one of those prints will lack the non-ascii characters. Seems like as soon as you try to grab the file names to loop over they will be ascii only. Anyone have any ideas on this? Or can Qt simply not handle this? Thanks!
I know this is an old question, but I just ran into the same problem. The same exact Qt code would work fine on my development VM, but when I transferred it to an embedded Linux system (running on x86 so literally the same executable) my directory names just silently got their non-ASCII characters dropped.
Turned out the QTextCodec::codecForLocale on my dev VM was set to UTF-8, and on the embedded box it was System. If I manually changed the locale to UTF-8 before doing any filesystem operations (by calling QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"))), everything started working fine.
So why was this happening in the first place? My suspicion is that in the process of slimming down the embedded system's root filesystem I might have accidentally deleted some locale-related files that Qt was using to try to auto-detect the locale. When it couldn't determine it was on UTF-8, it fell back to System, which for whatever reason is broken (maybe for the same reason it couldn't detect UTF-8 in the first place).
I need to eventually fix whatever is causing it to not auto-detect, but in the short-term just manually setting a UTF-8 locale should work if you are experiencing this same issue.
Note that this has nothing to do with whether the console can display UTF-8, or anything to do with manual conversion of UTF-16 to UTF-8! So Felix's answer to this question is not correct, at least for this particular issue. To completely remove the capability of the console from the equation, I was also simply printing the number of UTF-16 characters in the string, and every non-ASCII character actually made the returned path and filename strings from QDir::entryInfoList have one less UTF-16 character. Additionally, the dead giveaway is that the characters were simply stripped out, not just replaced with garbage or question marks or whatever.
Qt can handle filenames with special characters. You just make them disappear somewhere in that string conversion stuff. (Which is completly unnecessary) Try it this way:
#include <QDebug>
//...
QFileInfoList fileInfoList = someDir.entryInfoList(QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files);
foreach(QFileInfo fileInfo, fileInfoList)
{
qDebug() << fileInfo.fileName();//uses qdebug
std::cout << fileInfo.fileName().toStdWString() << std::endl;//uses a 16Bit string on normal cout
}
If you still don't see them, it's because your console settings do not allow to display them. Try to write them to a file or display them in a gui - or simply try to open a file with that name, it will work.

corrupt data in decode base64 to image in Qt

I write a program decode the base64 string to image. I wrote a sample:
QFile file("./image.jpg");
if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
return;
}
QByteArray raw = file.readAll().toBase64();
QImage = image;
image.loadFromData(QByteArray::fromBase64(raw), "JPG");
image.save("output.jpg", "JPG");
The output of the program is:
Corrupt JPEG data: 65 extraneous bytes before marker 0xc0
Quantization table 0x01 was not defined
I can't find something useful with google. I only read image file, and encode it with base64, then decode it. Could you tell me what's wrong with my code?
I have figured out what's wrong with my code. When i open a image file, i use the QIODevice::Text open mode. But the image is a binary file, so i should remove the QIODevice::Text option. After do that, the code run well.

Resources