Get Pixmap out of Xlib - xlib

I've been trying to find a way of grabbing video directly from an X window and got pointed to Xlib and the compositing extension.
So far, I've been able to listen to change events and grab a Pixmap with this code:
#include <X11/Intrinsic.h>
#include <X11/extensions/Xcomposite.h>
#include <X11/extensions/Xdamage.h>
#include <iostream>
#include <fstream>
using namespace std;
int main(int argc, char ** argv) {
int br, base;
Window win = 0x3400003;
Display *dsp = XOpenDisplay(0);
XCompositeQueryExtension(dsp, &base, &br);
XDamageQueryExtension(dsp,&base, &br);
cout << base << endl;
Damage damage = XDamageCreate(dsp, win, XDamageReportRawRectangles);
XCompositeRedirectWindow(dsp, win, CompositeRedirectAutomatic);
XEvent ev;
while(true) {
XNextEvent(dsp, &ev);
if(ev.type == base + XDamageNotify) {
Pixmap pm = XCompositeNameWindowPixmap(dsp, win);
XWindowAttributes attr;
XGetWindowAttributes(dsp, win, &attr);
XWriteBitmapFile(dsp, "test.bmp", pm, attr.width, attr.height, -1, -1);
return 0;
}
}
XCompositeUnredirectWindow(dsp, win, CompositeRedirectAutomatic);
XDamageDestroy(dsp, damage);
return 0;
}
The problem here is that the resulting bmp (created by XWriteBitmapFile) is black&white horribleness. Disregarding the fact that I don't want to write the data to file anyway, I am apparently doing something wrong in reading it.
I would love to convert the Pixmap to either a framebuffer in opengl or a binary blob in ram.
Thanks in advance for any help you can give me on this.
Best regards.

"Bitmaps" in X world refer to two-colored images. I guess XWriteBitmapFile does internally GetImage request and transforms server pixmap to a bitmap. Note that file format is it's own 'X11 bitmap', not windows bitmap.
Use XGetImage function If you actually need image's binary blob.

Related

QChart with QAreaSeries with large data is very slow

I am playing around with QCharts (using area chart example as a template).
I am drawing an area chart with 10000 points in each of the series, and am finding that it is very slow, 30s for the window to appear and resizing the window results in the process hanging, its unusable for this dataset . Any ideas what could be wrong here ? I have seen that disabling anti aliasing might help, however it doesn't.
I have the folllowing code
#include <QtWidgets/QApplication>
#include <QtWidgets/QMainWindow>
#include <QtCharts/QChartView>
#include <QtCharts/QLineSeries>
#include <QtCharts/QAreaSeries>
#include <QRandomGenerator>
#include <QDateTime>
#include <QtCharts/QHXYModelMapper>
#include <QTimer>
#include "boost/range/irange.hpp"
QT_CHARTS_USE_NAMESPACE
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
auto *upper = new QLineSeries;
auto *lower = new QLineSeries;
auto *generator = QRandomGenerator::global();
const auto maxSamples = 10000;
for(auto x : boost::irange(0, maxSamples))
{
lower->append(QPointF(x, 0));
upper->append(QPointF(x, generator->bounded(0, 100)));
}
auto *series = new QAreaSeries(upper, lower);
QChart *chart = new QChart();
chart->addSeries(series);
chart->createDefaultAxes();
chart->legend()->setVisible(false);
chart->axisY(series)->setRange(0, 100);
QChartView *chartView = new QChartView(chart);
//chartView->setRenderHint(QPainter::Antialiasing);
QMainWindow window;
window.setCentralWidget(chartView);
window.resize(800, 600);
window.show();
return a.exec();
}
Any ideas what could be the problem here?
We have bounced into this times ago and found that the implementation of append() in a QXYSeries was suboptimal and was consuming a lot of time with large datasets.
To improve the performance, we now use:
void QXYSeries::replace(QVector<QPointF> points)
with a local vector that we first allocate to the dataset size, and then fill with the actual data.
With large datasets, you may still have performance issues, depending on the type of series, due to the construction of the graphics items used to render the series.

QPrinter + QPainter writes invalid PDF file

I am simply trying to draw a rectangle to a PDF file using QPrinter + QPainter:
#include <QtWidgets>
#include <QPrinter>
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
QPrinter printer(QPrinter::HighResolution);
printer.setOutputFileName("/Users/jason/Desktop/example.pdf");
printer.setOutputFormat(QPrinter::PdfFormat);
QPainter painter;
painter.begin(&printer);
int width = painter.viewport().width();
int height = painter.viewport().height();
painter.setPen(Qt::black);
painter.drawRect(0.25*width, 0.25*height, 0.5*width, 0.5*height);
painter.end();
}
Using MacOS 10.15.4 and Qt 5.15.2 this results in a blank/invalid PDF file. The same code without the QPrinter.setOutputFormat and QPrinter.setOutputFileName correctly prints a rectangle on paper.
How can I using QPrinter/QPdfWriter + QPainter to draw to a PDF file?
I am a fool. I thought the PDF was blank, but it turns out if I zoom in really really far, I can see a faint grey line. Apparently the resolution of a PDF is much higher than that of my printer!
Using painter.setPen(QPen(QBrush(Qt::red), 100.0)) shows a clear rectangle as expected.

Saving video as series of images opencv

This question is in continuation of error-in-opencv-code-for-motion-detection. The editted code works without any errors but the output video is not created,it is of zero bytes!What is wrong in this?Also,the bounding box created for motion detection never really captures the motion that is, it does not do what it originally claimed to do.Am I misunderstanding something about the objective of thie code?So, here are my questions:
How to rectify the creation and save the video?
What needs to be modified to detect motion and track it?
How to convert the video to a series of numbered jpg images from each frame and vice-versa.
Here is the code which you can work with to frame a video as a set of images.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "cv.h"
#include <highgui.h>
#include "cxcore.h"
int main( int argc, char** argv )
{
CvCapture *capture = cvCaptureFromAVI("E:\\Myvideo.avi");
if(!capture)
{
printf("!!! cvCaptureFromAVI failed (file not found?)\n");
return -1;
}
int fps = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
printf("* FPS: %d\n", fps);
IplImage* frame = NULL;
int frame_number = 0;
char key = 0;
while (key != 'q')
{
// get frame
frame = cvQueryFrame(capture);
if (!frame)
{
printf("!!! cvQueryFrame failed: no frame\n");
break;
}
// quit when user press 'q'
key = cvWaitKey(1000 / fps);
}
// free resources
cvReleaseCapture(&capture);
return 0;
}

OpenCV cannot load image

While I was working on a project, I noticed that I am not able to load images. Here is the simple code that I used to check:
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
if( argc != 2)
{
cout <<" Usage: display_image ImageToLoadAndDisplay" << endl;
return -1;
}
Mat image;
image = imread(argv[1], CV_LOAD_IMAGE_COLOR); // Read the file
if(! image.data ) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl ;
return -1;
}
Mat gray_image;
cv::cvtColor(image, gray_image, CV_RGB2GRAY);
imwrite("Gray_Image.jpg",gray_image);
return 0;
}
Here is its output when I execute it:
root#beaglebone:~# ./tryit lena.jpg
Could not open or find the image
I tried to directly use the address of the image ("/home/root/lena.jpg") instead of argv[1] but nothing changed.
What can be the problem?
ps: I am cross-compiling this OpenCV program and then running it on my BeagleBone which has Angstrom Linux installed on it. Can this problem related to it?
I solved my problem by deleting existing OpenCV libraries on my angstrom image and replacing them with the working ones.
Try saving the image with a png extension and then opening it. For some reason, files with a png extension work better than other extensions like jpg/gif.

Resizing a cell's height and Witdth and loading an image in QTableWidget

I want to make a 8*8 table with square cells ( a chess board ). Now I have the code to make the table but don't know how to resize the cells to be square shaped.
I also want to put pictures of pieces into the cells. How should I do these?
here is the code i have:
#include <QtGui/QApplication>
#include "mainwindow.h"
#include <QHBoxLayout>
#include <QTableWidget>
class Table : public QWidget
{
public:
Table(QWidget *parent = 0);
};
Table::Table(QWidget *parent)
: QWidget(parent)
{
QHBoxLayout *hbox = new QHBoxLayout(this);
QTableWidget *table = new QTableWidget(8 , 8 , this);
hbox->addWidget(table);
setLayout(hbox);
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Table t;
t.show();
return a.exec();
}
EDIT:
If anyone can help me with loading an image as the background of cell too, it would be very appreciated!
I use this code and compiler does not generate an error but program fails to run. I think the problem is with the table->item(0,0). Should I initialize it first?
QString fileName = "1.bmp";
QPixmap pic (fileName);
QIcon icon (pic);
table->item(0,0)->setIcon(icon);
To make the cells square shaped do something like this:
// set the default size, here i've set it to 20px by 20x
table->horizontalHeader()->setDefaultSectionSize(20);
table->verticalHeader()->setDefaultSectionSize(20);
// set the resize mode to fixed, so the user cannot change the height/width
table->horizontalHeader()->setResizeMode(QHeaderView::Fixed);
table->verticalHeader()->setResizeMode(QHeaderView::Fixed);
Edit: To set the images, set the icon attribute on your QTableWidgetItems
after searching and searching and searching.... I finally got the answer. I should first make a QBrush object and set it as a background of a QtableWidgetItem and then use table->setItem !!!
QString fileName = "/1.bmp";
QPixmap pic (fileName);
QBrush brush(pic);
QTableWidgetItem* item = new QTableWidgetItem();
item->setBackground(brush);
table->setItem(0,0,item);

Resources