mirror of
https://github.com/Yubico/yubioath-flutter.git
synced 2024-11-22 16:32:01 +03:00
Include above-and-left-of-primary pixels in QR screenshots
`QGuiApplication::primaryScreen()->grabWindow(...)` only includes pixels below and to the right of the top left corner of the primary screen (at least in Linux). Consider a screen arrangement like: +-------------+ +---------++---------+| | + || || | + 3 || PRIMARY || 2 | +---------++---------++-------------+ With this screen arrangement, the top of screen 2 and all of screen 3 would be left out of the screenshot. Combining the results of calling `grabWindow(...)` on each `QScreen` resolves the issue.
This commit is contained in:
parent
c219b26cf2
commit
8584c8b3a5
48
screenshot.h
48
screenshot.h
@ -10,28 +10,46 @@ public:
|
||||
explicit ScreenShot () : QObject() {}
|
||||
// Take a screenshot, convert it to a bitarray and return it with some metadata
|
||||
Q_INVOKABLE QVariantMap capture() {
|
||||
QScreen *screen = QGuiApplication::primaryScreen();
|
||||
// Virtual geometry grabs all pixels on the desktop, even with multiple monitors.
|
||||
QRect g = screen->virtualGeometry();
|
||||
QPixmap screenShot = screen->grabWindow(0, g.x(), g.y(), g.width(), g.height());
|
||||
// Monochrome, no dither
|
||||
QImage image = screenShot.toImage();
|
||||
image = image.convertToFormat(QImage::Format_Mono, Qt::ThresholdDither);
|
||||
// Get all pixels as 1 (black) or 0 (white)
|
||||
QByteArray imageArray;
|
||||
for (int row = 0; row < image.height(); ++row) {
|
||||
for (int col = 0; col < image.width(); ++col) {
|
||||
QRgb px = image.pixel(col, row);
|
||||
if (px == 0xFF000000) {
|
||||
imageArray.append((char) 1);
|
||||
} else {
|
||||
|
||||
// Dimensions of output image
|
||||
int outputHeight = 0;
|
||||
int outputWidth = 0;
|
||||
for (QScreen *screen : QGuiApplication::screens()) {
|
||||
outputWidth = std::max(outputWidth, screen->geometry().width());
|
||||
}
|
||||
|
||||
for (QScreen *screen : QGuiApplication::screens()) {
|
||||
QRect g = screen->geometry();
|
||||
QPixmap screenShot = screen->grabWindow(0, 0, 0, g.width(), g.height());
|
||||
|
||||
// Monochrome, no dither
|
||||
QImage image = screenShot.toImage();
|
||||
image = image.convertToFormat(QImage::Format_Mono, Qt::ThresholdDither);
|
||||
|
||||
// Stack screens vertically in output image
|
||||
outputHeight += image.height();
|
||||
for (int row = 0; row < image.height(); ++row) {
|
||||
for (int col = 0; col < image.width(); ++col) {
|
||||
QRgb px = image.pixel(col, row);
|
||||
if (px == 0xFF000000) {
|
||||
imageArray.append((char) 1);
|
||||
} else {
|
||||
imageArray.append((char) 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Pad smaller screens horizontally
|
||||
for (int col = image.width(); col < outputWidth; ++col) {
|
||||
imageArray.append((char) 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QVariantMap map;
|
||||
map.insert("width", image.width());
|
||||
map.insert("height", image.height());
|
||||
map.insert("width", outputWidth);
|
||||
map.insert("height", outputHeight);
|
||||
map.insert("data", QString(imageArray.toBase64()));
|
||||
return map;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user