How to draw image in Linux at same time on LCD and HDMI on Raspberry Pi with QT?
Asked Answered
C

1

0

Does anyone knows how to draw an image in Linux, Raspberry Pi, Qt with double framebuffer in same time. I mean i want to run my application on LCD display and draw image to HDMI in same time.

Carlo answered 21/6, 2016 at 12:54 Comment(4)
I think the preferred format for this kind of thing is to ask a question and then answer it yourself. You may want to explain it all a bit more so it's clear to future readers.Mallissa
This is not a question! Please put all the answer into an answer, and then edit the question to be a question. It is perfectly fine to answer your own questions!Denesedengue
Why add extra code instead of just running your program with QT_QPA_PLATFORM=linuxfb, QT_QPA_GENERIC_PLUGINS=evdevtouch,evdevmouse,evdevkeyboard, QT_QPA_EVDEV_KEYBOARD_PARAMETERS=grab=1in its environment - isn't that the whole point of using a cross-platform library such as Qt?Delisadelisle
because you can't work with double framebuffer in same time in QT. Try to execute your program using /dev/fb1 and set image to /dev/fb0 - that why that code exists. have a funCarlo
C
0

I wrote this code, but I saw a lot of questions on the Internet how to display the image on Linux fraimbuffer. I'll leave it here, maybe someone need help with it. That code was tested on Raspberry Pi 2 model B,B+ and Linux Kernel 4.4.y. with Qt 5.6

File: fbdi.pro

QT += core
QT += gui
QT += widgets
CONFIG += c++11
TARGET = fbdi
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += fbdi.cpp

File: fbdi.cpp

#include <QDebug>
#include <QImage>
#include <QRgb>
#include <sys/mman.h>
#include <sys/fcntl.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <unistd.h>

#define FB_ERROR_OPEN_FBD 0x0001  // Could not open the framebuffer device
#define FB_ERROR_READ_FSI 0x0002  // Read fixed display information failed
#define FB_ERROR_READ_VSI 0x0004  // Read variable display information failed
#define FB_ERROR_MAPS_MEM 0x0008  // Mapping memory failed
#define FB_ERROR_LOAD_IMG 0x0016  // Load image file failed
#define FB_ERROR_TRAN_IMG 0x0032  // Transformation image file

struct fb_fix_screeninfo;
struct fb_var_screeninfo;

typedef fb_fix_screeninfo finfo;
typedef fb_var_screeninfo vinfo;

struct linuxfb_t {
    int     device;     // file handler
    uint8_t *data;      // data ptr
    finfo   fix_info;   // fixed display information
    vinfo   var_info;   // variable display information
    int     err_code;   // error code
    char    *err_mesg;  // error mesage
    long    screensize; // calculated screen size
};

///
/// \brief  fb_error     Set error code and message
/// \param  fb           Pointer to struct linuxfb_t
/// \param  code         Error number
/// \param  message      Error message
/// \return bool         Always false
///
bool fb_error(linuxfb_t *fb, int code, QString message)
{
    fb->err_code = code;
    fb->err_mesg = message.toLocal8Bit().data();
    return false;
}

///
/// \brief fb_fatal     Output message if an error accurred
/// \param fb           Pointer to struct linuxfb_t
/// \return int         Error code
///
int fb_fatal(linuxfb_t *fb)
{
    qDebug("Error %d: %s", fb->err_code, fb->err_mesg);
    return fb->err_code;
}


///
/// \brief fb_draw      Draw specified image on linux framebuffer
/// \param fb           Pointer to struct linuxfb_t
/// \param device       Path to linux framebuffer device (eg. /dev/fb0)
/// \param filename     Path to image file which support by Qt
/// \return bool        True if the function success, overwise false
///
bool fb_draw(linuxfb_t *fb, const char *device, const char *filename)
{
    fb->device = open(device, O_RDWR);

    if( fb->device < 0 ) {
        return fb_error(fb, FB_ERROR_OPEN_FBD, QString("Unable to open specified device"));
    }

    if( ioctl(fb->device, FBIOGET_VSCREENINFO, &fb->var_info) ) {
        return fb_error(fb, FB_ERROR_READ_VSI, QString("Unable to read variable screen information"));
    }

    if( ioctl(fb->device, FBIOGET_FSCREENINFO, &fb->fix_info) ) {
        return fb_error(fb, FB_ERROR_READ_FSI, QString("Unable to get fixed screen information"));
    }

    fb->screensize = fb->var_info.xres * fb->var_info.yres * (fb->var_info.bits_per_pixel/8);
    fb->data = (uint8_t *) mmap(0, fb->screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fb->device, (off_t) 0);

    if( (intptr_t) fb->data == -1 ) {
        return fb_error(fb, FB_ERROR_MAPS_MEM, QString("Failed to map framebuffer device to memory"));
    }

    QImage img_orig;
    if( !img_orig.load(filename) ) {
        munmap(fb->data, fb->screensize);
        close(fb->device);
        return fb_error(fb, FB_ERROR_LOAD_IMG, "Could not open the file you specified");
    }

    QImage img_trans;
    img_trans = img_orig.scaled(fb->var_info.xres, fb->var_info.yres);
    if( img_trans.isNull() ) {
        munmap(fb->data, fb->screensize);
        close(fb->device);
        return fb_error(fb, FB_ERROR_TRAN_IMG, "Could not transform image");
    }

    for( uint32_t x=0; x < fb->var_info.xres; x++ ) {
        for( uint32_t y=0; y < fb->var_info.yres; y++ ) {
            long location = (x+fb->var_info.xoffset) * (fb->var_info.bits_per_pixel/8) +
                            (y+fb->var_info.yoffset) * fb->fix_info.line_length;

            QRgb color = img_trans.pixel(x,y);
            uint32_t pixel = (qRed(color)<<fb->var_info.red.offset)     |
                             (qGreen(color)<<fb->var_info.green.offset) |
                             (qBlue(color)<<fb->var_info.blue.offset)   ;

            *((uint32_t*)(fb->data+location)) = pixel;
        }
    }

    munmap(fb->data, fb->screensize);
    close(fb->device);

    return true;
}

///
/// \brief  main Application entry point
/// \return result
///
int main()
{
    // Create linuxfb variable
    linuxfb_t fb;

    // Output some image
    if( !fb_draw(&fb, "/dev/fb0", "/tmp/test.png") ) {

        // Failed
        return fb_fatal(&fb);
    }

    // success
    return 0;
}
Carlo answered 22/6, 2016 at 15:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.