C++ Linux绘制像素缓冲区

C++ Linux绘制像素缓冲区,c++,c,linux,gdk,C++,C,Linux,Gdk,问题很简单,我有一个生成像素缓冲区的代码。现在我需要呈现这个像素缓冲区,而不是保存图像,然后在保存后进行分析 以下问题的解决方案是什么: 开窗 将此窗口中的所有像素替换为我的像素RGB888 到目前为止,建议是:使用opengl,为覆盖窗口的矩形创建顶点缓冲区,并使用像素着色器绘制像素。这显然不是在窗口中交换像素缓冲区的最佳方法 平台:Ubuntu 18 可以使用哪个是一个小的、快速的、现代的C++库。它是“仅标题”,因此没有复杂的链接或依赖关系 // http://cimg.eu/refer

问题很简单,我有一个生成像素缓冲区的代码。现在我需要呈现这个像素缓冲区,而不是保存图像,然后在保存后进行分析

以下问题的解决方案是什么:

  • 开窗
  • 将此窗口中的所有像素替换为我的像素RGB888
  • 到目前为止,建议是:使用opengl,为覆盖窗口的矩形创建顶点缓冲区,并使用像素着色器绘制像素。这显然不是在窗口中交换像素缓冲区的最佳方法

    平台:Ubuntu 18

    可以使用哪个是一个小的、快速的、现代的C++库。它是“仅标题”,因此没有复杂的链接或依赖关系

    // http://cimg.eu/reference/group__cimg__tutorial.html
    
    #include <iostream>
    #include <string>
    #include "CImg.h"
    
    using namespace cimg_library;
    
    int main(int argc,char **argv) {
    
       const unsigned char white[] = { 255,255,255 };
       const int width  = 320;
       const int height = 240;
       // Create 3-channel RGB image
       CImg<> img(width,height,1,3);
    
       // Create main window
       CImgDisplay main_window(img,"Random Data",0);
       int frame = 0;
    
       while (!main_window.is_closed()) {
         // Fill image with random noise
         img.rand(0,255);
         // Draw in frame counter
         std::string text = "Frame: " + std::to_string(frame);
         img.draw_text(10,10,text.c_str(),white,0,1,32);
         main_window.display(img);
         frame++;
         std::cout << "Frame: " << frame << std::endl;
       }
    }
    
    还要注意,我正在使用
    img.rand()
    用数据填充图像,您需要获取
    img.data()
    ,它是指向像素缓冲区的指针,然后
    memcpy()
    将图像数据放入该地址的缓冲区

    请注意,我还做了一些直接在中写入帧缓冲区的工作。这是在Python中,但是它很容易适应。

    < p>你可以使用哪个是一个小的、快速的、现代的C++库。它是“仅标题”,因此没有复杂的链接或依赖关系

    // http://cimg.eu/reference/group__cimg__tutorial.html
    
    #include <iostream>
    #include <string>
    #include "CImg.h"
    
    using namespace cimg_library;
    
    int main(int argc,char **argv) {
    
       const unsigned char white[] = { 255,255,255 };
       const int width  = 320;
       const int height = 240;
       // Create 3-channel RGB image
       CImg<> img(width,height,1,3);
    
       // Create main window
       CImgDisplay main_window(img,"Random Data",0);
       int frame = 0;
    
       while (!main_window.is_closed()) {
         // Fill image with random noise
         img.rand(0,255);
         // Draw in frame counter
         std::string text = "Frame: " + std::to_string(frame);
         img.draw_text(10,10,text.c_str(),white,0,1,32);
         main_window.display(img);
         frame++;
         std::cout << "Frame: " << frame << std::endl;
       }
    }
    
    还要注意,我正在使用
    img.rand()
    用数据填充图像,您需要获取
    img.data()
    ,它是指向像素缓冲区的指针,然后
    memcpy()
    将图像数据放入该地址的缓冲区


    请注意,我还做了一些直接在中写入帧缓冲区的工作。这是用Python编写的,但它很容易修改。

    您也可以很容易地在窗口中显示位图图像。事实上,它似乎比我的另一个答案中的CImg要快得多。我不是这方面的专家,但以下代码似乎满足了您的需求:

    // g++ -std=c++11 main.cpp $(pkg-config --libs --cflags sfml-graphics sfml-window)
    
    #include <SFML/Graphics.hpp>
    #include <iostream>
    #include <cstdint>
    
    int main()
    {
        const unsigned width = 1024;
        const unsigned height= 768;
    
        // create the window
        sf::RenderWindow window(sf::VideoMode(width, height), "Some Funky Title");
    
        // create a texture
        sf::Texture texture;
        texture.create(width, height);
    
        // Create a pixel buffer to fill with RGBA data
        unsigned char *pixbuff = new unsigned char[width * height * 4];
        // Create uint32_t pointer to above for easy access as RGBA
        uint32_t * intptr = (uint32_t *)pixbuff;
    
        // The colour we will fill the window with
        unsigned char red  = 0;
        unsigned char blue = 255;
    
        // run the program as long as the window is open
        int frame = 0;
        while (window.isOpen())
        {
            // check all the window's events that were triggered since the last iteration of the loop
            sf::Event event;
            while (window.pollEvent(event))
            {
                // "close requested" event: we close the window
                if (event.type == sf::Event::Closed)
                    window.close();
            }
    
            // clear the window with black color
            window.clear(sf::Color::Black);
    
            // Create RGBA value to fill screen with.
            // Increment red and decrement blue on each cycle. Leave green=0, and make opaque
            uint32_t RGBA;
            RGBA = (red++ << 24) | (blue-- << 16) | 255;
            // Stuff data into buffer
            for(int i=0;i<width*height;i++){
               intptr[i] = RGBA;
            }
            // Update screen
            texture.update(pixbuff);
            sf::Sprite sprite(texture);
            window.draw(sprite);
    
            // end the current frame
            window.display();
            std::cout << "Frame: " << frame << std::endl;
            frame++;
            if(frame==1000)break;
        }
    
        return 0;
    }
    
    //g++-std=c++11 main.cpp$(pkg-config--libs--cflags-sfml图形sfml窗口)
    #包括
    #包括
    #包括
    int main()
    {
    常数无符号宽度=1024;
    常数无符号高度=768;
    //创建窗口
    渲染窗口(sf::视频模式(宽度、高度),“一些时髦的标题”);
    //创建纹理
    sf::纹理;
    纹理。创建(宽度、高度);
    //创建像素缓冲区以填充RGBA数据
    无符号字符*pixbuff=新的无符号字符[宽度*高度*4];
    //创建指向上面的uint32\u t指针,以便作为RGBA轻松访问
    uint32_t*intptr=(uint32_t*)pixbuff;
    //我们将用什么颜色填满窗户
    无符号字符红色=0;
    无符号字符蓝色=255;
    //只要窗口打开,就运行程序
    int帧=0;
    while(window.isOpen())
    {
    //检查自上次循环迭代以来触发的所有窗口事件
    sf::事件;
    while(window.pollEvent(事件))
    {
    //“请求关闭”事件:我们关闭窗口
    如果(event.type==sf::event::Closed)
    window.close();
    }
    //用黑色清除窗户
    窗口。清除(sf::颜色::黑色);
    //创建RGBA值以填充屏幕。
    //在每个循环中递增红色,递减蓝色。保留绿色=0,并使其不透明
    uint32_t RGBA;
    
    RGBA=(红色+++您也可以在窗口中非常轻松地显示位图图像。事实上,它似乎比我的另一个答案中的CImg快得多。我在这方面不是专家,但以下代码似乎满足了您的要求:

    // g++ -std=c++11 main.cpp $(pkg-config --libs --cflags sfml-graphics sfml-window)
    
    #include <SFML/Graphics.hpp>
    #include <iostream>
    #include <cstdint>
    
    int main()
    {
        const unsigned width = 1024;
        const unsigned height= 768;
    
        // create the window
        sf::RenderWindow window(sf::VideoMode(width, height), "Some Funky Title");
    
        // create a texture
        sf::Texture texture;
        texture.create(width, height);
    
        // Create a pixel buffer to fill with RGBA data
        unsigned char *pixbuff = new unsigned char[width * height * 4];
        // Create uint32_t pointer to above for easy access as RGBA
        uint32_t * intptr = (uint32_t *)pixbuff;
    
        // The colour we will fill the window with
        unsigned char red  = 0;
        unsigned char blue = 255;
    
        // run the program as long as the window is open
        int frame = 0;
        while (window.isOpen())
        {
            // check all the window's events that were triggered since the last iteration of the loop
            sf::Event event;
            while (window.pollEvent(event))
            {
                // "close requested" event: we close the window
                if (event.type == sf::Event::Closed)
                    window.close();
            }
    
            // clear the window with black color
            window.clear(sf::Color::Black);
    
            // Create RGBA value to fill screen with.
            // Increment red and decrement blue on each cycle. Leave green=0, and make opaque
            uint32_t RGBA;
            RGBA = (red++ << 24) | (blue-- << 16) | 255;
            // Stuff data into buffer
            for(int i=0;i<width*height;i++){
               intptr[i] = RGBA;
            }
            // Update screen
            texture.update(pixbuff);
            sf::Sprite sprite(texture);
            window.draw(sprite);
    
            // end the current frame
            window.display();
            std::cout << "Frame: " << frame << std::endl;
            frame++;
            if(frame==1000)break;
        }
    
        return 0;
    }
    
    //g++-std=c++11 main.cpp$(pkg-config--libs--cflags-sfml图形sfml窗口)
    #包括
    #包括
    #包括
    int main()
    {
    常数无符号宽度=1024;
    常数无符号高度=768;
    //创建窗口
    渲染窗口(sf::视频模式(宽度、高度),“一些时髦的标题”);
    //创建纹理
    sf::纹理;
    纹理。创建(宽度、高度);
    //创建像素缓冲区以填充RGBA数据
    无符号字符*pixbuff=新的无符号字符[宽度*高度*4];
    //创建指向上面的uint32\u t指针,以便作为RGBA轻松访问
    uint32_t*intptr=(uint32_t*)pixbuff;
    //我们将用什么颜色填满窗户
    无符号字符红色=0;
    无符号字符蓝色=255;
    //只要窗口打开,就运行程序
    int帧=0;
    while(window.isOpen())
    {
    //检查自上次循环迭代以来触发的所有窗口事件
    sf::事件;
    while(window.pollEvent(事件))
    {
    //“请求关闭”事件:我们关闭窗口
    如果(event.type==sf::event::Closed)
    window.close();
    }
    //用黑色清除窗户
    窗口。清除(sf::颜色::黑色);
    //创建RGBA值以填充屏幕。
    //在每个循环中递增红色,递减蓝色。保留绿色=0,并使其不透明
    uint32_t RGBA;
    
    RGBA=(红色++任何GUI工具包都可以做到这一点:例如Qt或GTK。@Thomas你可以更具体地说明方法,哪些调用可以执行任务。到目前为止,是的,我用GTK打开了窗口,但找不到一种方法来显示我自己。这是一个绘图小部件,我很熟悉。我想问的是如何在没有widget的情况下完成它。你的目标是什么?尽可能少地编写代码?尽可能快地更新屏幕?最重要的是什么?@MarkSetchell基本上我有一些来自外部设备的输入,输入被解析,图形表示被计算。我需要将这些像素数组显示在窗口中。所以我有一个缓冲区,它需要因此,我正在寻找一种方法来修改当前窗口的像素缓冲区,最好使用smth(如libx11),而不必深入小部件库的兔子洞,cairoAny GUI toolkit可以做到这一点:例如Qt或GTK。@Thomas你能更具体地说明方法吗,哪些调用可以执行任务。到目前为止,是的,我有wind现在打开GTK,但找不到一种方法来利用屏幕显示我自己这是一个