QImage+QPainter+QPdfWriter + newPage() = working code
-
@Christian-Ehrlicher said in QImage+QPainter+QPdfWriter + newPage() = working code:
This does not even compile.
sorry - fixed. I did not copy as single piece all code. coz it's slightly scattered throughout the class functions.
-
@wrosecrans said in QImage+QPainter+QPdfWriter + newPage() = working code:
If you want help with specific problems
I don't quite understand what specific problem I could single out to get help on solving it.
There is only one problem - there is no final PDF file with a new page and a new image on the last page.
And so - everything is compiled, linked, launched, works ... BUT there is no desired result.
According to the documentation and a mini-example of working python code, it is clear that for C ++ code, too, should not be required to be complex, long, etc. BUT the practice of running this mini-code shows that there is some kind of a bunch of problems that SOMETHING needs to be solved. For that garbage in the PDF file, which is nevertheless generated, cannot be the desired result. Those it turns out that the C++ code needs to add some kind of checks, corrections, clarifications or PDF properties, or images. Maybe additional scaling? Changing proportions? As you can see, I can't even figure out what's wrong here - because the simplest code from the documentation simply turned out to be unable to do what was written about it. Although this was not expected. -
@RazerMind said in QImage+QPainter+QPdfWriter + newPage() = working code:
because the simplest code from the documentation simply turned out to be unable to do what was written about it.
Doubt.
According to the documentation and a mini-example of working python code, it is clear that for C ++ code, too, should not be required to be complex, long, etc. BUT the practice of running this mini-code shows that there is some kind of a bunch of problems that SOMETHING needs to be solved. For that garbage in the PDF file, which is nevertheless generated
I also doubt that you properly convert Qt code written in Python to C++ and it suddenly produces garbage, while the Python way seem to work.
Debug your code, set breakpoints, check expected results and check WHY it outputs garbage in your case.
Check if you file is valid, if your image data is valid and everything was correctly initialized.
You are not the first one, who uses this Qt C++ module/class and tries to write content to a new PDF page.
If you still need help, you should post what you've done exactly and not snippets grabbed from here and there out of your classes. -
@Pl45m4
Ok, feel free to reuse next code for your own tests:class PdfDocument { public: PdfDocument(const QString& fileName); virtual ~PdfDocument(); bool isReady() const { return m_file != nullptr && m_writer != nullptr; } const QString& get_errorMsg() const { return errorMsg; } bool addImageToPdf(const QByteArray& imageData); private: QFile* createFile(const QString& fileName, QString& error) QPdfWriter* createPdfWriter() const; private: QString outputFileName; QFile* m_file; QPdfWriter* m_writer; QString errorMsg; }; PdfDocument::PdfDocument(const QString& fileName) : outputFileName(fileName), m_file(nullptr), m_writer(nullptr), errorMsg("impossible error") { m_file = createFile(outputFileName, errorMsg); if (m_file) m_writer = createPdfWriter(); } PdfDocument::~PdfDocument() { m_file->close(); delete m_writer; delete m_file; } QFile* PdfDocument::createFile(const QString& fileName, QString& error) { QFile* file = new QFile(fileName); if (file->exists()) { if (!file->open(QIODevice::Append)) { error = QStringLiteral("Cannot open file for appending: %0").arg(file->errorString()); delete file; return nullptr; } } else { if (!file->open(QIODevice::WriteOnly)) { error = QStringLiteral("Cannot create file: %0").arg(file->errorString()); delete file; return nullptr; } } return file; } QPdfWriter* PdfDocument::createPdfWriter() const { QPdfWriter* writer = new QPdfWriter(m_file); writer->setPageSize(QPageSize(QPageSize::A4)); writer->setResolution(72); writer->setPageOrientation(QPageLayout::Orientation::Landscape); return writer; } bool PdfDocument::addImageToPdf(const QByteArray& imageData) { if (!m_writer) return false; // impossible case, but... QImage image = QImage::fromData(imageData); if (image.isNull()) { errorMsg = QStringLiteral("Cannot load image from data."); return false; } QPainter painter(m_writer); if (!m_writer->newPage()) { errorMsg = QStringLiteral("Cannot add new page at PDF file for further work."); return false; } painter.drawImage(QPointF(0, 0), image); return true; } // somewhere in the code: PdfDocument pdf("full_PDF_pathName_onDisk"); if (!pdf.isReady()) { //produce general error message, use also and pdf.get_errorMsg() //about this bad case and return false; }else{ QByteArray singlePage = //get it from response of 3rd component = webclient; return pdf.addImageToPdf(singlePage); }
-
@RazerMind said in QImage+QPainter+QPdfWriter + newPage() = working code:
QByteArray singlePage = //get it from response of 3rd component = webclient;
return pdf.addImageToPdf(singlePage);Without testing (I will later), are you sure that the data (i.e. either your web response or your bytearray) you receive is 100% valid and you are not getting your "garbage" already there?
Something like this in
addImageToPdf
QImage image = QImage::fromData(imageData); if (image.isNull()) { errorMsg = QStringLiteral("Cannot load image from data."); return false; } QLabel lbl; lbl.setPixmap(QPixmap::fromImage(image)); lbl.show(); // QPainter stuff // ...
-
@RazerMind said in QImage+QPainter+QPdfWriter + newPage() = working code:
I don't quite understand what specific problem I could single out to get help on solving it.
There is only one problem - there is no final PDF file with a new page and a new image on the last page.Part of programming is learning to break problems down into smaller problems. The QPainter API's work on any surface, like a QIMage that you can save to a PNG, or a QWidget. So, are you drawing what you want to draw correctly? If you can replicate the issue on something other than a PDF, then the problem has nothing to do with a PDF.
Does drawing on everything but a PDF work? Then the problem is specific to making a PDF.
Break the problem down into smaller pieces like that. Are you saying there is no PDF file at all? In your sentence you lump "final PDF file with a new page and a new image on the last page" into a single concept like it has irreducible complexity, so I can't even tell if you made an empty PDF or a PDF with multiple pages but the wrong content, or no file, etc.
-
@wrosecrans
ok for the very beginning - you can try to reuse my code from above. What you will get?
Of course here will be small problem - how to obtain bytearray of input image in your case....
....................Aha! one idea I have: the best variant in this ase should be: open any small pdf you have with
help of class QPdfDocument and render it into QImage class))) {https://doc.qt.io/qt-5/qpdfdocument.html#render}
So We can kill two birds with one stone this way.- We will be sure that we get a valid image. It will not depend on what and where the photo/image you can find && download. With what resolution? What size? Who knows. And so everything is already predetermined.
- Because If you take some ready-made PDF file (with 1/2/3 pages max!), then trying to add an Image to the new one being created, you will, as it were, have to completely repeat your original PDF file! Of course, I'm not talking about bit similarity, but about the same content when viewing. But the essence does not change from this. You should have two PDF files on your disk after the code runs. One initial, let's say with 3 original pages, and one final, created as a result of running the C++ code, which was supposed to take the first page from the original PDF file and repeat it. Accordingly, when you open these two files in AdobeAcrobat for ex., the first two pages must absolutely match, because one page will be just the source, and the second one will be just a literal copy, because it is made on the basis of the complete image from this first page.
-
@RazerMind said in QImage+QPainter+QPdfWriter + newPage() = working code:
100000% sure.
So how does the image look? If the
QLabel
is shown correctly, we can be sure that it's a PDFWriter issue -
I made some tests and played around a bit.
My conclusion:
This works flawless. Generates a
PDF.pdf
with three pages, on each page the image, starting at (0,0).QImage img("Path/to/Image.png"); QPdfWriter* writer = new QPdfWriter("Path/to/Pdf.pdf"); writer->setPageSize(QPageSize(QPageSize::A4)); writer->setResolution(72); writer->setPageOrientation(QPageLayout::Orientation::Landscape); QPainter painter(writer); for (int i=0; i<3; ++i) { painter.drawImage(QPoint(0, 0), img); writer->newPage(); }
Then I used your class / code, using the same image.
It works, BUT only as long as the PDF file doesn't exists.Maybe somebody can correct me, if I'm wrong, but
QPdfWriter
is a generator for PDF files. For invoices, small documents and other stuff. AFAIK it's not designed to continue to write to already existing PDF files or append any content "out of the box" (which you tried to do).
TheQPainter
onQPdfWriter
didn't care much aboutQFile(QIODevice::Append))
, since it resets and starts from the beginning of the file.Also,
QPdfWriter::newPage()
creates a new page and then the painter jumps there. Since append doesn't work, it starts at page 1, creates a new one and paints the image on page 2, leaving the first (starting) page blank.
Doing the same on the same file again, doesn't append either. It creates the same file again (blank first page, then image on second).There's nothing wrong with your code and probably not with your
QByteArray
, it's unfortunately not how it works withQPdfWriter
/QPainter
:(
I guess, you have to find another way or use external pdf libs. -
@Pl45m4 said in QImage+QPainter+QPdfWriter + newPage() = working code:
AFAIK it's not designed to continue to write to already existing PDF files or append any content "out of the box" (which you tried to do).
Yep, looks like you are right. And I should stop using this flawless library at all((((((
But huge thx for all this "testing" stuff... -
Have a look at LibHaru, esp. the Graphics part