简体   繁体   English

将图像放入 x11 的窗口中

[英]Putting image into a Window in x11

I have a QR code in .JPG format.我有一个 .JPG 格式的二维码。 I load it using OpenCV 3.4.4.我使用 OpenCV 3.4.4 加载它。 Now, I create a new X11 window using XCreateSimpleWindow().现在,我使用 XCreateSimpleWindow() 创建一个新的 X11 窗口。 Then, I will resize the QR image to that of this new window.然后,我会将 QR 图像的大小调整为这个新窗口的大小。

Next, I want to put this resized QR code into the window.接下来,我想把这个调整大小的二维码放到窗口中。 I tried using XPutImage(), but without any success, probably because I don't know the usage.我尝试使用 XPutImage(),但没有成功,可能是因为我不知道用法。

For using XPutImage(), I first took the image of the X11 window using XGetImage();为了使用 XPutImage(),我首先使用 XGetImage() 获取 X11 窗口的图像; then obtained the pixel values of the QR image, then assigned that to the pixel value of the image obtained through XGetImage.然后获取QR图像的像素值,然后将其分配给通过XGetImage获取的图像的像素值。

Once I had this XImage, I tried putting it to the window using XPutImage.一旦我有了这个 XImage,我就尝试使用 XPutImage 把它放到窗口中。 But, it is still showing a black window.但是,它仍然显示一个黑色窗口。 There is no error in the terminal, but result is not as desired.终端没有错误,但结果不理想。

Any solution to this problem?这个问题有什么解决办法吗? Like, how to change the background of the window (X11) wrt a sample image, and using XPutImage()?例如,如何更改窗口 (X11) 的背景并使用 XPutImage() 编写示例图像?

The code goes like this...代码是这样的......

// Written by Ch. Tronche (http://tronche.lri.fr:8000/)
// Copyright by the author. This is unmaintained, no-warranty free software. 
// Please use freely. It is appreciated (but by no means mandatory) to
// acknowledge the author's contribution. Thank you.
// Started on Thu Jun 26 23:29:03 1997

//
// Xlib tutorial: 2nd program
// Make a window appear on the screen and draw a line inside.
// If you don't understand this program, go to
// http://tronche.lri.fr:8000/gui/x/xlib-tutorial/2nd-program-anatomy.html
//

//  compilation:
//              g++ -o go qrinX11.cpp `pkg-config --cflags --libs opencv` -lX11
//

#include <opencv2/opencv.hpp>
#include "opencv2/opencv.hpp"   // FOR OpenCV
#include <opencv2/core.hpp>     // Basic OpenCV structures (cv::Mat)
#include <opencv2/videoio.hpp>  
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>

#include <bits/stdc++.h>
#include <X11/Xlib.h> // Every Xlib program must include this
#include <assert.h>   // I include this to test return values the lazy way
#include <unistd.h>   // So we got the profile for 10 seconds
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <X11/Xlib.h> // Every Xlib program must include this
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/extensions/Xcomposite.h>
#include <X11/extensions/Xfixes.h>
#include <X11/extensions/shape.h>
#define NIL (0)       // A name for the void pointer

using namespace cv;
using namespace std;

int main()
{

      XGCValues gr_values;
      //GC gc;
      XColor    color, dummy;


      Display *dpy = XOpenDisplay(NIL);
      //assert(dpy);
      //int screen = DefaultScreen(dpy);
      // Get some colors

      int blackColor = BlackPixel(dpy, DefaultScreen(dpy));
      int whiteColor = WhitePixel(dpy, DefaultScreen(dpy));

      // Create the window

      Window w = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, 
                     200, 100, 0, whiteColor, blackColor);

      // We want to get MapNotify events

      XSelectInput(dpy, w, StructureNotifyMask);

      XMapWindow(dpy, w);

      // Wait for the MapNotify event

      for(;;) {
        XEvent e;
        XNextEvent(dpy, &e);
        if (e.type == MapNotify)
          break;
      }

    Window focal = w;

    XWindowAttributes gwa;
    XGetWindowAttributes(dpy, w, &gwa); 
    int wd1 = gwa.width;
    int ht1 = gwa.height;



    XImage *image = XGetImage(dpy, w, 0, 0 , wd1, ht1, AllPlanes, ZPixmap);
    unsigned long rm = image->red_mask;
    unsigned long gm = image->green_mask;
    unsigned long bm = image->blue_mask;

    Mat img(ht1, wd1, CV_8UC3);             // OpenCV Mat object is initilaized
    Mat scrap = imread("qr.jpg");//(wid, ht, CV_8UC3);      
    resize(scrap, img, img.size(), CV_INTER_AREA);

    for (int x = 0; x < wd1; x++)
        for (int y = 0; y < ht1 ; y++)
        {
            unsigned long pixel = XGetPixel(image,x,y);     
            unsigned char blue = pixel & bm;                // Applying the red/blue/green mask to obtain the indiv channel values
            unsigned char green = (pixel & gm) >> 8;
            unsigned char red = (pixel & rm) >> 16;     

            Vec3b color = img.at<Vec3b>(Point(x,y));        // Store RGB values in the OpenCV image


            //color[0] = blue;
            //color[1] = green;
            //color[2] = red;
            //img.at<Vec3b>(Point(x,y)) = color;


            pixel = color[0];//&color[1]&color[2];

        }   

        namedWindow("QR", CV_WINDOW_NORMAL);
        imshow("QR", img);

        cout << "herererere\n";
        GC gc = XCreateGC(dpy, w, 0, NIL);
        XPutImage(dpy, w, gc, image, 0, 0, wd1, ht1, wd1, ht1);

    waitKey(0);
//sleep(3);
    return 0;
}

Alright, solved it on my own.好的,我自己解决了。 There was a silly mistake at changing the pixel value and updating it to the actual image and then putting it to the background of the window.在更改像素值并将其更新为实际图像,然后将其放入窗口背景时,存在一个愚蠢的错误。

First use XPutPixel() , then use XPutImage()首先使用XPutPixel() ,然后使用XPutImage()

Here is the final and correct method:这是最终的正确方法:

//  compilation:
//              g++ -o go qrinX11.cpp `pkg-config --cflags --libs opencv` -lX11
//

#include <opencv2/opencv.hpp>
#include "opencv2/opencv.hpp"   // FOR OpenCV
#include <opencv2/core.hpp>     // Basic OpenCV structures (cv::Mat)
#include <opencv2/videoio.hpp>  
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>

#include <bits/stdc++.h>
#include <X11/Xlib.h> // Every Xlib program must include this
#include <assert.h>   // I include this to test return values the lazy way
#include <unistd.h>   // So we got the profile for 10 seconds
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <X11/Xlib.h> // Every Xlib program must include this
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/extensions/Xcomposite.h>
#include <X11/extensions/Xfixes.h>
#include <X11/extensions/shape.h>
#define NIL (0)       // A name for the void pointer

using namespace cv;
using namespace std;

int main()
{

      XGCValues gr_values;
      //GC gc;
      XColor    color, dummy;


      Display *dpy = XOpenDisplay(NIL);
      //assert(dpy);
      //int screen = DefaultScreen(dpy);
      // Get some colors

      int blackColor = BlackPixel(dpy, DefaultScreen(dpy));
      int whiteColor = WhitePixel(dpy, DefaultScreen(dpy));

      // Create the window

      Window w = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, 
                     200, 100, 0, whiteColor, blackColor);

      // We want to get MapNotify events

      XSelectInput(dpy, w, StructureNotifyMask);

      XMapWindow(dpy, w);

      // Wait for the MapNotify event

      for(;;) {
        XEvent e;
        XNextEvent(dpy, &e);
        if (e.type == MapNotify)
          break;
      }

    Window focal = w;

    XWindowAttributes gwa;
    XGetWindowAttributes(dpy, w, &gwa); 
    int wd1 = gwa.width;
    int ht1 = gwa.height;



    XImage *image = XGetImage(dpy, w, 0, 0 , wd1, ht1, AllPlanes, ZPixmap);
    unsigned long rm = image->red_mask;
    unsigned long gm = image->green_mask;
    unsigned long bm = image->blue_mask;

    Mat img(ht1, wd1, CV_8UC3);     // OpenCV Mat object is initilaized
    Mat scrap = imread("qr.jpg");//(wid, ht, CV_8UC3);      
    resize(scrap, img, img.size(), CV_INTER_AREA);

    for (int x = 0; x < wd1; x++)
        for (int y = 0; y < ht1 ; y++)
        {
            unsigned long pixel = XGetPixel(image,x,y);     

            Vec3b color = img.at<Vec3b>(Point(x,y));



            pixel = 65536 * color[2] + 256 * color[1] + color[0];               

            XPutPixel(image, x, y, pixel);                  
        }   

    namedWindow("QR", CV_WINDOW_NORMAL);
    imshow("QR", img);


    GC gc = XCreateGC(dpy, w, 0, NIL);
    XPutImage(dpy, w, gc, image, 0, 0, 0, 0, wd1, ht1);

    waitKey(0);    
    return 0;
}

Simplicity is key, and improves performance (in this case):简单是关键,并提高性能(在这种情况下):

//.. 

// Mat img(ht1, wd1, CV_8UC3);     // OpenCV Mat object is initilaized
cv::Mat img(ht1, wd1, CV_8UC4, image->data);  // initilaize with existing mem
Mat scrap = imread("qr.jpg");//(wid, ht, CV_8UC3); 
cv::cvtColor(scrap,scrap,cv::COLOR_BGR2BGRA);
resize(scrap, img, img.size(), cv::INTER_AREA);    

// .. and we can skip the for loops 

namedWindow("QR", CV_WINDOW_NORMAL);
imshow("QR", img);

// .. etc

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM