ben.ezazi
Posts: 3
Joined: Wed Aug 22, 2018 9:55 am

dispmanx show picture

Wed Aug 22, 2018 11:02 am

Hello

I'm trying to show a picture on the screen using dispmanx and openCV.

what i did was opening the picture vai openCV lib:
Mat img = cv::imread(myPng.png, cv::IMREAD_COLOR);
then i tried to pass the data of the image to the Rect object to show it:
vars->image=img.data;
but everytime i get the error: Assertion `ret == 0' failed.

anybody knows how to handle this?

here is the code im working on:

Code: Select all

/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of the copyright holder nor the
      names of its contributors may be used to endorse or promote products
      derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/


#include <iostream>
#include <memory>
#include <cstdlib>
#include <cassert>
#include <vector>

#include "bcm_host.h"

#include <opencv2/core/core.hpp>

#include <opencv2/highgui/highgui.hpp>

#ifndef ALIGN_UP 
#define ALIGN_UP(x,y) ((x + (y)-1) & ~((y)-1)) 
#endif

class Rect {
    static int rectCount;
    static DISPMANX_DISPLAY_HANDLE_T   display;
    static DISPMANX_MODEINFO_T         info;
    static DISPMANX_RESOURCE_HANDLE_T  resource;
    void                              *image;
    static DISPMANX_UPDATE_HANDLE_T    update;
    DISPMANX_ELEMENT_HANDLE_T          element;
    uint32_t                           vc_image_ptr;
    VC_RECT_T       src_rect;
    VC_RECT_T       dst_rect;
    VC_DISPMANX_ALPHA_T alpha;
    int x, y;
    int width, height;
    int pitch;
    int aligned_height;
    VC_IMAGE_TYPE_T type;

public:
    Rect(int x, int y, int width, int height):x(x),y(y),width(width),height(height) {
        if(display == 0) {
            bcm_host_init();

            display = vc_dispmanx_display_open(5);
            int ret = vc_dispmanx_display_get_info(display, &info);
            assert(ret == 0); 
            std::cout << "Display:  " << info.width << " x " << info.height << std::endl;
        }   
        pitch = ALIGN_UP(width*2, 32);
        aligned_height = ALIGN_UP(height, 16);
        type = VC_IMAGE_RGB565;

	cv::Mat img = cv::imread("t.png" , cv::IMREAD_COLOR);
	image=img.data;

    assert(image);
    }

    int getCount() { return rectCount; }

    void beforeDraw() {
        resource = vc_dispmanx_resource_create(type,
                                               width,
                                               height,
                                               &vc_image_ptr);
        assert(resource);
        update = vc_dispmanx_update_start(0);
        assert(update);
    }

    void draw(int layer) {
        VC_DISPMANX_ALPHA_T alpha = {
                        DISPMANX_FLAGS_ALPHA_FROM_SOURCE,
                        255, /*alpha 0->255*/
                        0
        };

        vc_dispmanx_rect_set(&dst_rect, 0, 0, width, height);
        int ret = vc_dispmanx_resource_write_data(resource,
                      type,
                      pitch,
                      image,
                      &dst_rect);
        assert(ret == 0);

        vc_dispmanx_rect_set(&src_rect, 0, 0, width << 16, height << 16);

        vc_dispmanx_rect_set(&dst_rect, x, y, width, height);

        element = vc_dispmanx_element_add(update,
                      display,
                      layer,        // layer
                      &dst_rect,
                      resource,
                      &src_rect,
                      DISPMANX_PROTECTION_NONE,
                      &alpha,
                      NULL,        // clamp
                      DISPMANX_NO_ROTATE);
    }

    void afterDraw() {
        int ret = vc_dispmanx_update_submit_sync(update);
        assert(ret == 0);
    }

    ~Rect() {
        free(image);
        update = vc_dispmanx_update_start(0);
        assert(update);
        int ret = vc_dispmanx_element_remove(update, element);
        assert(ret == 0);
        ret = vc_dispmanx_update_submit_sync(update);
        assert(ret == 0);
        rectCount--;
        if(rectCount == 0) {
            std::cout << "No more rectangles" << std::endl;
            ret = vc_dispmanx_resource_delete(resource);
            assert(ret == 0);
            ret = vc_dispmanx_display_close(display);
            assert(ret == 0);
            display = 0;
        }
    }

};

DISPMANX_DISPLAY_HANDLE_T Rect::display = 0;
int Rect::rectCount = 0;
DISPMANX_MODEINFO_T Rect::info;
DISPMANX_RESOURCE_HANDLE_T Rect::resource;
DISPMANX_UPDATE_HANDLE_T Rect::update;

int main(void)
{
    int width = 1920;
    int height = 1080;
    int i=0;
    std::vector<std::shared_ptr<Rect>> rects;
    std::shared_ptr<Rect> r = std::make_shared<Rect>(0, 0, width, height);
    r->beforeDraw();
    r->draw(i+5);
    rects.push_back(r);
    rects[0]->afterDraw();
    sleep(2);
    return 0;
}
p.s I am very new to this topic this question might lack enough info, I will try to add information to it

User avatar
AndyD
Posts: 2327
Joined: Sat Jan 21, 2012 8:13 am
Location: Melbourne, Australia
Contact: Website

Re: dispmanx show picture

Thu Aug 23, 2018 9:26 am

I have some code on github that will display a PNG file using dispmanx, that you may be worth a look.

https://github.com/AndrewFromMelbourne/raspidmx

ben.ezazi
Posts: 3
Joined: Wed Aug 22, 2018 9:55 am

Re: dispmanx show picture

Thu Aug 23, 2018 12:19 pm

Thank you Andrew already have looked at your code, I must say its very well written one :P because even with my very rusty knowledge of C i could pick up some stuff. however not only i must do my code in c++ but also the program must support more than only .png extensions(.jpg,..etc).

And I must add that I am new to this topic.

the following is the code im working on currently which is a bit faulty:

notice: this code has small changes in it from the code above.


Code: Select all

/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of the copyright holder nor the
      names of its contributors may be used to endorse or promote products
      derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/


#include <iostream>
#include <memory>
#include <cstdlib>
#include <cassert>
#include <vector>

#include "bcm_host.h"

#include <opencv2/core/core.hpp>

#include <opencv2/highgui/highgui.hpp>

#ifndef ALIGN_UP 
#define ALIGN_UP(x,y) ((x + (y)-1) & ~((y)-1)) 
#endif

class Rect {
    static int rectCount;
    static DISPMANX_DISPLAY_HANDLE_T   display;
    static DISPMANX_MODEINFO_T         info;
    static DISPMANX_RESOURCE_HANDLE_T  resource;
    void                              *image;
    static DISPMANX_UPDATE_HANDLE_T    update;
    DISPMANX_ELEMENT_HANDLE_T          element;
    uint32_t                           vc_image_ptr;
    VC_RECT_T       src_rect;
    VC_RECT_T       dst_rect;
    VC_DISPMANX_ALPHA_T alpha;
    int x, y;
    int width, height;
    int pitch;
    int aligned_height;
    VC_IMAGE_TYPE_T type;

public:
    Rect(int x, int y, int width, int height, unsigned char* data):x(x),y(y),width(width),height(height) {
        if(display == 0) {
            bcm_host_init();
            display = vc_dispmanx_display_open(5);
            int ret = vc_dispmanx_display_get_info(display, &info);
            assert(ret == 0); 
            std::cout << "Display:  " << info.width << " x " << info.height << std::endl;
        }   
//        pitch = ALIGN_UP(width*2, 32);
        pitch = ALIGN_UP(width*3, 32);
        aligned_height = ALIGN_UP(height, 16);
//        type = VC_IMAGE_BGRX8888;
        type = VC_IMAGE_BGR888;
//        image = calloc(1, pitch * height);

	image=data;

	assert(image);

   }

    int getCount() { return rectCount; }

    void beforeDraw() {
        resource = vc_dispmanx_resource_create(type,
                                               width,
                                               height,
                                               &vc_image_ptr);
        assert(resource);
        update = vc_dispmanx_update_start(0);
        assert(update);
    }

    void draw(int layer) {
        VC_DISPMANX_ALPHA_T alpha = {
                        DISPMANX_FLAGS_ALPHA_FROM_SOURCE,
                        120, /*alpha 0->255*/
                        0
        };

        vc_dispmanx_rect_set(&dst_rect, 0, 0, width, height);
        int ret = vc_dispmanx_resource_write_data(resource,
                      type,
                      pitch,
                      image,
                      &dst_rect);
        assert(ret == 0);

        vc_dispmanx_rect_set(&src_rect, 0, 0, width << 16, height << 16);

        vc_dispmanx_rect_set(&dst_rect, x, y, width, height);

        element = vc_dispmanx_element_add(update,
                      display,
                      layer,        // layer
                      &dst_rect,
                      resource,
                      &src_rect,
                      DISPMANX_PROTECTION_NONE,
                      &alpha,
                      NULL,        // clamp
                      DISPMANX_NO_ROTATE);
    }

    void afterDraw() {
        int ret = vc_dispmanx_update_submit_sync(update);
        assert(ret == 0);
    }

    ~Rect() {
        update = vc_dispmanx_update_start(0);
        assert(update);
        int ret = vc_dispmanx_element_remove(update, element);
        assert(ret == 0);
        ret = vc_dispmanx_update_submit_sync(update);
        assert(ret == 0);
        rectCount--;
        if(rectCount == 0) {
            std::cout << "No more rectangles" << std::endl;
            ret = vc_dispmanx_resource_delete(resource);
            assert(ret == 0);
            ret = vc_dispmanx_display_close(display);
            assert(ret == 0);
            display = 0;
        }
    }

};

DISPMANX_DISPLAY_HANDLE_T Rect::display = 0;
int Rect::rectCount = 0;
DISPMANX_MODEINFO_T Rect::info;
DISPMANX_RESOURCE_HANDLE_T Rect::resource;
DISPMANX_UPDATE_HANDLE_T Rect::update;

int main(void)
{
    int width = 1920;
    int height = 1080;
    int i=0;

    std::vector<std::shared_ptr<Rect>> rects;

    cv::Mat img = cv::imread("/home/pi/myDispmanx/t.png" , CV_LOAD_IMAGE_COLOR);

    std::shared_ptr<Rect> r = std::make_shared<Rect>(0, 0, width, height, img.data);
	
    r->beforeDraw();

    r->draw(i+5);

    rects.push_back(r);

    rects[0]->afterDraw();

    sleep(2);
    return 0;
}

this code mostly does the trick but in some cases it projects a distorted image.
e.g the following pc will be shown distorted. Image
notice for this picture I changed the

Code: Select all

int width;
and

Code: Select all

int height;
values to match the cat.png dimensions.
Attachments
cat.png
cat.png (41.37 KiB) Viewed 1377 times

User avatar
ksharindam
Posts: 96
Joined: Sat Jan 09, 2016 4:16 pm

Re: dispmanx show picture

Thu Sep 06, 2018 6:21 pm

ben.ezazi wrote:
Thu Aug 23, 2018 12:19 pm
this code mostly does the trick but in some cases it projects a distorted image.
e.g the following pc will be shown distorted.
Upload an image in which case it shows correct image
My Qt projects at ... https://github.com/ksharindam

Return to “Graphics programming”