Print QWebPage to pixmap - qt

I'm not the most experienced in Qt or desktop development, so I hope this isn't too much of an ignorant question.
I am trying to use QWebKit [1] to store a webpage to images as if printed on paper. Unfortunately it seems that QPainter works only for printing to pdf, postscript or a real printer, and QWebFrame doesn't have methods to set the media to CSS in case of rendering to a QPainter.
I can see that inside Qt QPrintPreviewWidgetPrivate uses printer->d_func()->previewPages(); to get a preview of the images that will be sent to the printer, however this is a private method and not a publicly available API and therefore I cannot use it even if it were possible to get the images at a desired resolution.
At this point I am at a loss and might actually start delving into how QPrinter and QWebFrame interact and just re-implement the methods in hope that it isn't too big of an undertaking.
[1] Unfortunately can't upgrade to Qt5 and QWebEngine yet.

Related

Why is my QML CJK text being rendered with corrupt glyphs?

My application allows the user to switch languages on the fly. I'm seeing that about 10% of the time the user switches to Chinese or Japanese, the glyphs for the UI text are being rendered improperly.
This application is running under Linux on an iMX6 platform. Qt 5.5.0 is being used. QML is used to render the UI. The corrupt text is being rendered using a QML Text control.
Example of corrupt font rendering
The font being used in question is Source Hans Sans Regular. I have tried loading this using a QML FontLoader and by loading it on the C++ side into the application font database (both methods exhibited the problem). I've tried using the (admittedly very strongly related) Noto fonts; same problem.
I have never seen corruption of text rendering when using Roboto for non-CJK text and, as mentioned, this works more often than not for CJK/Source Hans Sans.
The corruption is interesting because it looks like it is at the rendered bitmap level, not the glyph definition level (notice how some glyphs have the lower half correct, but the top half is corrupt).
Corruption does sometimes progress. This leads me to think the glyph bitmap cache memory is being overwritten further (just a theory as I'm not sure how Qt does font rendering). I thought it might be the QML garbage collection doing something odd, but loading the font on the C++ side didn't make a difference.
I'm going to try using 'native rendering' for the QML Text controls next.
Has anyone seen this before? Can anyone confirm FreeType is used for font management/rendering under Qt 5.5.0? Are there ways to influence how that font bitmap cache is managed?
Thanks!
Update: using 'renderType: Text.NativeRendering' did not eliminate the problem (although the corruption manifested slightly differently). And, given the limitations of that mode, just ended up with generally poorly rendered text (soft, poor scaling, etc - as documented).
Update 2: I built Qt with (as far as I know) all of the glyph caches disabled -- shouldDrawCachedGlyphs() returns false in my local build for the four instances of that call I was able to find -- but still encountered glyph corruption.
Update 3: Tried switching to use the software (non-OpenGL) Qt Quick 2 renderer by setting QMLSCENE_DEVICE=softwarecontext per docs; glyph corruption still occurred.
In this particular case, there is a bug in the OpenGL driver on the platform I'm working with. It affects FBO readbacks. Setting QML_USE_GLYPHCACHE_WORKAROUND=1 in the environment forces Qt to keep an additional copy of the glyph cache in RAM (since it cannot be read back from the graphics hardware when new glyphs are added).
The implication of this is that while rendering will be correct (since we're using a second cache which isn't corrupt) performance will be degraded slightly since there is an extra copy on the CPU and the glyph cache will use twice as much memory. Rendering quality is unaffected.
Qt support was able to point me in the right direction and qualify the implications associated with QML_USE_GLYPHCACHE_WORKAROUND.

How to print a QQuickView's contents to PDF?

I'm upgrading some Qt (C++ & QML) code from Qt4.8 to Qt5.1.
The Qt4.8 code is a trivial C++ "QML viewer" app subclassing a QDeclarativeView, and a bunch of QML.
It's been easy enough to change this to use Qt5/QtQuick2's QQuickView except for one thing:
The Qt4.8 app has a method for printing to PDF:
void MyQMLViewer::printToPDF(const QString& filename) const {
QPrinter printer(QPrinter::HighResolution);
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setPageSize(QPrinter::A3);
printer.setOutputFileName(filename);
printer.setOrientation(QPrinter::Landscape);
QPainter painter(&printer);
render(&painter);
}
There were a few "environment" changes needed for Qt5.1 to get a QPrinter (ie add QT += printsupport to the project .pro file and #include <QtPrintSupport>), but there seems to be a more fundamental problem that QQuickView doesn't provide anything which is obviously compatible with the QGraphicsView/QPainter/QPaintDevice world of QPrinter (specifically, QQuickView has no render method, and all the drawing/painting/rendering-related methods it does have seem very tied up with OpenGL).
Any suggestions for how to best obtain high-quality PDF output from a QQuickView ?
(Note that I am not simply looking to screenshot the view; with QDeclarativeView, the code above generates PDFs with much better resolution even than the app fullscreened on my largest monitor).
I see the "QDeclarativeItem and QDeclarativeView" section of the "Porting QML Applications to Qt 5" guide does mention the loss of QGraphicsView-specific functionality, but doesn't offer any solutions (although it does mention workrounds for the case of items with custom QPainter-based rendering being bought into the new regime).
Update with some additional background info: an example of a PDF printed from QDeclarativeView using the above code can be found here. There's a png of the same view on a decent size monitor here. (This is actually the last slide in a series of slides; it's actually a gallery of the previous slides which bounces each slide onto the screen; if I had the time I'd look into the feasibility of the gallery being the only thing and transforming each scattered slide into view for a Prezi-style presentation; suspect QDeclarative isn't really performant enough though, which is one reason for wanting to get onto QtQuick2+Qt5.2's new scene graph stuff). Anyway, If you zoom the PDF up to 100% you'll see the text is... well it's better than anything a sanely sized image file will manage I think, although the sloping text baselines perhaps look a little uneven. There is also an issue with opacity values not being represented in the PDF (so the drop shadows and "bubbles" come out solid); another one of my motivations for trying for a QtQuick2 version was actually to see if translucent elements were dealt with any better. I assume the PDF just contains rasterized (or maybe vector outlines) of all the elements as utilities like "pdftotext" can't extract anything from it. I don't know enough about PDF tools to know how to inspect the internal structure of the thing but I assume there's some hierarchy there and the QML element tree is all laid out using a similar structure of nested transforms to the QML. Just for comparison and the sort of richness I'm potentially working towards here's a poster I did with LaTeX/Beamerposter; I find Beamerposter's rigid block structure rather limiting (and fiddly) compared with the possibilities QML seems to offer though. BTW, another thing on my wishlist/todolist is a QML element which can render LaTeX source, math and all, just to get the best of both worlds.
Update: Recent Qt blog post on all the backend changes in Qt5.8 has a comment linking to this Qt issue to use the new possibility of QPainter-rendered QtQuick scenes to render PDFs.
At the moment, there is no code in Qt that supports rendering of a scene graph to a pdf. The underlying data that is used to render Qt Quick 2 is held in the scene graph. As Laszlo suggests, you'd need to iterate the scene graph and generate PDF primitives. There's some impedance mismatch there, but it should be doable with some sweat. I think a proof of concept could be small enough to fit here, so I'll see how easy it could be :)
If you really want a PDF, you currently have no choice but to render it to a large image at 300dpi and wrap that in a PDF. The image doesn't have to be large if the poster has large areas of solid color. PDF can do do TIFF encoding and also JPEG encoding.

How to render custom video data in Qt ?

I have never done a Qt video application - newbie in this area. I have a custom video file format to render using Qt. The video file format is 256-byte header, then pixel data, then 256-byte header, then pixel data and so on.
The header consist info like width, height in pixels, bytes per pixels, frame rate etc and the pixel data is in Bayer (GBRG). I may have to process data before display - like convert to RGB (not sure yet). I see there are lot of video related classes like QGL*, QMovie, QVideo* ... don't know where to start ? I have seen mandelbrotwidget example which looks like a good place to start but still need some advice. Also, do I have to write a Qt Image plugin for Bayer pattern?
Thank you.
Good advice is to do all by yourself. If you have simple data structure read it by simple C++-code.
Conversation from Bayer RGB to RGB like here you can also make without using any Qt objects.
And now, when you'll got trivial RGB-image (even in your own structure) per frame, you can show it on widgets such as QGL* -- if you prefer OpenGL rendering, or Qt's classes such as QPainter, QImage...
Some more links: C++ GUI Programming with Qt4, 2nd Edition, Graphics View Framework
The best place to start is by learning the basics of custom drawing in Qt. In short, a very simple implementation would require you to:
Create a custom QWidget subclass
Override the paintEvent() method
Use a QPainter/QImage to decode your raw video data into image data and draw it on screen
Qt has lots of good sample code to get you started, such as:
http://qt-project.org/doc/qt-4.8/examples-painting.html
Once you have a simple implementation up and running, and a basic grasp of Qt concepts/classes, then you'll be ready to profile, optimize, and make use of more advanced Qt functionality (GL, video) as needed.

Get information about pics and video files with qt

Well i have a project in which gets pics and videos from folders and also i can view them it it and when i view them i want to also see those tags kinda like the camera which took it, dimensions , the ISO, the exposure time and others for pics and camera model framerate and dimensions...
Thanks in advance
I've never seen anything like this in Qt. Anyway, Qt is a C++ framework, you can use whatever library you want to use. QImageMetaData and QMeta are very near Qt style, but can only be used for images (never tried those).
Anyway, I would use the XMP toolkit. You also mentioned videos, so in that case XMP can handle both. It is very simple to use, well documented and fast (license is BSD). It is written in C++, so you can port it on whatever platform you want.
I think Qt itself does not provide a way to extract exif data (which is what I guess you're trying to extract). You could perhaps try QMeta. I have not used this myself, so no guarantees.

Qt+OpenGl+SimpleGl

I have enabled qt+OpenGl+SimpleGl on one of the ARM platform and was able to run opengl example programs.
I also has a qt+Webkit, which is working with a graphic plugin.
I wanted to use simpleGl context for every thing, instead of using the normal graphic screen. So, when I try to run Qt+Webkit with simpleGl, I just get a blank screen.
Does QT support this? If so how can we make it?
Yes, this is correct. OpenGL draws directly to the framebuffer. The simplegl driver doesn't handle what is drawn using the raster paint engine of the QWS, so you may see only black.
Using simplegl for "everything" means you want everything to be drawn using OpenGL in your EGL full-screen window? This is possible under some assumptions. You have to write all your applications to be rendered using the Qt OpenGL paint engine (using the opengl graphics system is not supported under Qt/E). This is possible also for QtWebKit, I'm doing it now. Note that this does not mean that everything is rendered using hardware acceleration. You'll have to write your applications "the right way" to get all actually hardware accelerated. Consider that you'll have to handle the mouse pointer some other way in this case.
The other way is to just modify the simplegl driver to allow for the use of Qt applications using the raster paint engine. This is possible as well with some limitations. Qt can use blit to place its own windows over OpenGL. Look for the framebuffer driver inside the Qt source tree to know how to do this. You can then have common Qt applications and OpenGL Qt applications some way. I'm doing this as well. Not everything can be done anyway.
EDIT: I'm sure you already did, but in case, give this http://doc.qt.io/qt-4.8/qt-embeddedlinux-opengl.html much attention.
Unfortunately I don't know anything about SimpleGL, but I do know that there is a way to render a standard Qt widget in a QGLWidget. Maybe have a look at this Qt Quarterly which I think is somewhat related to your question:
http://doc.qt.nokia.com/qq/qq26-openglcanvas.html

Resources