简单的方法在C / Linux中显示不断更新的图像 [英] Easy way to display a continuously updating image in C/Linux

查看:89
本文介绍了简单的方法在C / Linux中显示不断更新的图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是一名对C进行数值计算相当舒服的科学家,但我需要一些帮助来显示结果。我希望能够在一个窗口中显示一个连续更新的位图,这是从实时数据计算出来的。我希望能够很快更新图像(例如,快于1帧/秒,最好是100帧/秒)。例如:

  char image_buffer [width * height * 3]; // rgb data 
initializewindow();

for(t = 0; t {
getdata(data); //获得一些实时数据
docalcs(image_buffer,data) ; //将数据处理成图像
drawimage(image_buffer); //绘制图像
}

在linux(Ubuntu)上最简单的方法是什么?我应该如何使用initializewindow()和drawimage()?如果你想要做的就是显示数据(即,不需要GUI),您可能需要查看 SDL :它可以直接转到从像素数据创建一个表面上,然后屏幕上显示它。



Artelius的答案,我还破解了一个示例程序:

  #include< SDL / SDL.h> 
#include< assert.h>
#include< stdint.h>
#include< stdlib.h>

#define WIDTH 256
#define HEIGHT 256

static _Bool init_app(const char * name,SDL_Surface * icon,uint32_t flags)
{
atexit(SDL_Quit);
if(SDL_Init(flags)<0)
return 0;

SDL_WM_SetCaption(name,name);
SDL_WM_SetIcon(icon,NULL);

返回1;


static uint8_t * init_data(uint8_t * data)
{
for(size_t i = WIDTH * HEIGHT * 3; i--;)
data [i] =(i%3 == 0)? (i / 3)%WIDTH:
(i%3 == 1)? (i / 3)/ WIDTH:0;

返回数据;


静态_Bool进程(uint8_t * data)
{
for(SDL_Event event; SDL_PollEvent(& event);)
if .type == SDL_QUIT)返回0;
$ b $ for(size_t i = 0; i data [i] - = rand()%8 ;

返回1;


static void render(SDL_Surface * sf)
{
SDL_Surface * screen = SDL_GetVideoSurface();
if(SDL_BlitSurface(sf,NULL,screen,NULL)== 0)
SDL_UpdateRect(screen,0,0,0,0);


static int filter(const SDL_Event * event)
{return event-> type == SDL_QUIT; }
$ b $##define mask32(BYTE)(*(uint32_t *)(uint8_t [4]){[BYTE] = 0xff))

int main(int argc,char * argv [])
{
(void)argc,(void)argv;
static uint8_t buffer [WIDTH * HEIGHT * 3];

_Bool ok =
init_app(SDL示例,NULL,SDL_INIT_VIDEO)&&
SDL_SetVideoMode(WIDTH,HEIGHT,24,SDL_HWSURFACE);

assert(ok);

SDL_Surface * data_sf = SDL_CreateRGBSurfaceFrom(
init_data(缓冲液),宽度,高度,24,WIDTH * 3,
mask32(0),mask32(1),mask32(2 ),0);

SDL_SetEventFilter(filter); (; process(buffer); SDL_Delay(10))
render(data_sf);



返回0;
}


I'm a scientist who is quite comfortable with C for numerical computation, but I need some help with displaying the results. I want to be able to display a continuously updated bitmap in a window, which is calculated from realtime data. I'd like to be able to update the image quite quickly (e.g. faster than 1 frame/second, preferably 100 fps). For example:

char image_buffer[width*height*3];//rgb data
initializewindow();

for (t=0;t<t_end;t++)
{
   getdata(data);//get some realtime data
   docalcs(image_buffer, data);//process the data into an image
   drawimage(image_buffer);//draw the image
}

What's the easiest way to do this on linux (Ubuntu)? What should I use for initializewindow() and drawimage()?

解决方案

If all you want to do is display the data (ie no need for a GUI), you might want to take a look at SDL: It's straight-forward to create a surface from your pixel data and then display it on screen.

Inspired by Artelius' answer, I also hacked up an example program:

#include <SDL/SDL.h>
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>

#define WIDTH 256
#define HEIGHT 256

static _Bool init_app(const char * name, SDL_Surface * icon, uint32_t flags)
{
    atexit(SDL_Quit);
    if(SDL_Init(flags) < 0)
        return 0;

    SDL_WM_SetCaption(name, name);
    SDL_WM_SetIcon(icon, NULL);

    return 1;
}

static uint8_t * init_data(uint8_t * data)
{
    for(size_t i = WIDTH * HEIGHT * 3; i--; )
        data[i] = (i % 3 == 0) ? (i / 3) % WIDTH :
            (i % 3 == 1) ? (i / 3) / WIDTH : 0;

    return data;
}

static _Bool process(uint8_t * data)
{
    for(SDL_Event event; SDL_PollEvent(&event);)
        if(event.type == SDL_QUIT) return 0;

    for(size_t i = 0; i < WIDTH * HEIGHT * 3; i += 1 + rand() % 3)
        data[i] -= rand() % 8;

    return 1;
}

static void render(SDL_Surface * sf)
{
    SDL_Surface * screen = SDL_GetVideoSurface();
    if(SDL_BlitSurface(sf, NULL, screen, NULL) == 0)
        SDL_UpdateRect(screen, 0, 0, 0, 0);
}

static int filter(const SDL_Event * event)
{ return event->type == SDL_QUIT; }

#define mask32(BYTE) (*(uint32_t *)(uint8_t [4]){ [BYTE] = 0xff })

int main(int argc, char * argv[])
{
    (void)argc, (void)argv;
    static uint8_t buffer[WIDTH * HEIGHT * 3];

    _Bool ok =
        init_app("SDL example", NULL, SDL_INIT_VIDEO) &&
        SDL_SetVideoMode(WIDTH, HEIGHT, 24, SDL_HWSURFACE);

    assert(ok);

    SDL_Surface * data_sf = SDL_CreateRGBSurfaceFrom(
        init_data(buffer), WIDTH, HEIGHT, 24, WIDTH * 3,
        mask32(0), mask32(1), mask32(2), 0);

    SDL_SetEventFilter(filter);

    for(; process(buffer); SDL_Delay(10))
        render(data_sf);

    return 0;
}

这篇关于简单的方法在C / Linux中显示不断更新的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆