1

Hey All, I am trying to draw live images in Gtk::DrawingArea in the same way as they are shown in monitors at railway stations, airports, metro etc..

For current tesing purpose I have hardcoded my code.

here it is

Gtk::Drawing area width=720, height=640. I have first.pgm and second.pgm images each having 360*640 dimesions.(Yes, i rotated it for testing purpose.) These images contains one byte per pixel.

1) drawing fine when drwing single image. I just read the image into unsigned char* buffer of size 360*640*3. i have read it like this

int bufferIndex=0; 
int fileIndex=0; //just assume 
for (int i=0; i<height; i++)
{
     for (int j=0; j<width; j++)
     {
         //below three lines are for RGB purpose required in Gdk::Pixbuf
         buffer[bufferIndex++] = //File[fileIndex]; 
         buffer[bufferIndex++] = //File[fileIndex]; 
         buffer[bufferIndex++] = //File[fileIndex]; 
     }
}               

Gdk::Colorspace colorSpace = Gdk::COLORSPACE_RGB;
Gdk::Colorspace colorSpace = (Gdk::Colorspace)0;
bool has_alpha = false;
int bits_per_sample = 8;
int rowStride = 360*3; // distance between rows in bytes
Glib::RefPtr<Gdk::Pixbuf> pixBuf = Gdk::Pixbuf::create_from_data((const guint8 *) buffer,
       colorSpace, has_alpha, bits_per_sample, 360, 640, rowStride);
Glib::RefPtr<Gdk::GC> gcContext;
pixBuf->render_to_drawable(drawingArea pointer, gcContext, 0, 0, 0 , 0 , 360, 640, Gdk::RGB_DITHER_MAX, 0, 0);
//It prints the image in the left half of drawing area. 

It is the same as I expected, but there is an issue when I try to draw two images. For that purpose I read first.pgm in buffer and after that i read second.pgm (means total [360*640*3]*2 bytes) Now i draw it as shown in the code.

Glib::RefPtr<Gdk::GC>gcContext;
Gdk::Colorspace colorSpace = Gdk::COLORSPACE_RGB;
Gdk::Colorspace colorSpace = (Gdk::Colorspace)0;
bool has_alpha = false;
int bits_per_sample = 8;
int rowStride = 360*3; // distance between rows in bytes
Glib::RefPtr<Gdk::Pixbuf> pixBuf = Gdk::Pixbuf::create_from_data((const guint8 *) buffer,
       colorSpace, has_alpha, bits_per_sample, 720, 640, rowStride);
pixBuf->render_to_drawable(drawingarea pointer, gcContext, 0, 0, 0 , 0 , 720, 640, Gdk::RGB_DITHER_MAX, 0, 0);

In both halves, first.pgm is printed.

user1583846
  • 83
  • 2
  • 6

1 Answers1

2

You can open these images with the create_from_file() method, and copy to an other Pixbuf, which going to be displayed. Here is my code:

DrawingArea.h

#ifndef DRAWINGAREA_H
#define DRAWINGAREA_H

#include <gtkmm.h>


class DrawingArea : public Gtk::DrawingArea
{
public:
    DrawingArea();

protected:
    // Override default signal handler:
    virtual bool on_draw(const Cairo::RefPtr<Cairo::Context>& cr);
private:
    // 1.Pgm image
    Glib::RefPtr<Gdk::Pixbuf> image1;
    // 2.Pgm image
    Glib::RefPtr<Gdk::Pixbuf> image2;
    //Pixel buffer for display
    Glib::RefPtr<Gdk::Pixbuf> display;
    // Scale of the image
    double scale;
};
#endif // DRAWINGAREA_H

DrawingArea.cpp

#include "DrawingArea.h"

DrawingArea::DrawingArea()
{
    // Load the images
    image1 = Gdk::Pixbuf::create_from_file("first.pgm");
    image2 = Gdk::Pixbuf::create_from_file("second.pgm");
    //create a 720x640 rgb Pixbuf
    display = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB,0,8,720,640);
}
// Call when the display need to be updated
bool DrawingArea::on_draw(const Cairo::RefPtr<Cairo::Context>& cr)
{
    //copy the two images to the display Pixbuf with this function:
    //void Gdk::Pixbuf::copy_area   (int src_x,int src_y,int width,int height,const Glib::RefPtr< Gdk::Pixbuf >& dest_pixbuf,int dest_x,int dest_y)     
    image1->copy_area(0,0,360,640,display,0,0);
    image2->copy_area(0,0,360,640,display,360,0);
    // Place the display Pixbuf at the center of the window
    Gdk::Cairo::set_source_pixbuf(cr, display, 0,0);
    // Update the whole drawing area
    cr->rectangle(0, 0, display->get_width(), display->get_height());
    // Fill the area with the image
    cr->fill();
    // The event has been handled.
    return true;
}

And the main.cpp

#include <DrawingArea.h>
#include <gtkmm.h>


int main(int argc, char* argv[])
{
    // Initialize gtkmm and create the main window
    Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "betontaplfa");
    Gtk::Window window;

    // Create the drawing
    DrawingArea Dwg;
    // Insert the drawing in the window
    window.add(Dwg);
    // Resize the window
    window.resize(720,640);
    // Set the window title
    window.set_title("Pgm");
    // Show the drawing
    Dwg.show();

    // Start main loop
    return app->run(window);
}