【问题标题】:Putting image into a Window in x11将图像放入 x11 中的窗口
【发布时间】:2019-02-04 09:41:39
【问题描述】:

我有一个 .JPG 格式的二维码。我使用 OpenCV 3.4.4 加载它。现在,我使用 XCreateSimpleWindow() 创建一个新的 X11 窗口。然后,我会将 QR 图像的大小调整为这个新窗口的大小。

接下来,我想把这个调整大小的二维码放到窗口中。我尝试使用 XPutImage(),但没有任何成功,可能是因为我不知道用法。

为了使用 XPutImage(),我首先使用 XGetImage() 获取 X11 窗口的图像;然后获取QR图像的像素值,然后将其分配给通过XGetImage获得的图像的像素值。

一旦我有了这个 XImage,我尝试使用 XPutImage 将它放到窗口中。但是,它仍然显示一个黑色窗口。 终端没有错误,但结果不理想。

这个问题有什么解决办法吗?比如,如何改变窗口的背景(X11)w.r.t 一个示例图像,并使用 XPutImage()?

代码是这样的......

// 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;
}

【问题讨论】:

    标签: image c++14 x11 opencv3.0


    【解决方案1】:

    好的,我自己解决了。更改像素值并将其更新为实际图像,然后将其放置到窗口的背景中,这是一个愚蠢的错误。

    先用XPutPixel(),再用XPutImage()

    这是最终正确的方法:

    //  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;
    }
    

    【讨论】:

      【解决方案2】:

      简单是关键,并且可以提高性能(在这种情况下):

      //.. 
      
      // 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
      

      【讨论】:

        猜你喜欢
        • 2012-04-22
        • 1970-01-01
        • 2021-11-10
        • 2018-11-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多