linux开发板显示图片(如何在开发板上显示图片)

介绍

Linux开发板是一种嵌入式系统,可用于制作各种迷你电视机、IP电话、WiFi路由器、智能遥控和数字相机等。显示功能对于这些设备至关重要。本文将介绍如何在Linux开发板上显示图片。

使用Framebuffer

Framebuffer是Linux核心提供的一种图形驱动程序接口,其中包含有真实的物理输出设备信息,如分辨率、色彩空间、缓存区等。可在Framebuffer上使用成熟的Linux图形库,如DirectFB、GTK、Qt等。以下是在Linux开发板上显示图片的示例代码:


#include
#include
#include
#include
#include
#include

int main(int argc,char **argv)
{
int fd_dev;
char *mptr;
int n;

fd_dev=open("/dev/fb0",O_RDWR);
if(fd_dev==-1)
{
printf("Error:open Failed!\n");
exit(0);
}
mptr=mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,fd_dev,0);
if(mptr==MAP_FAILED)
{
printf("Error:mmap Failed!\n");
exit(0);
}
FILE *fp;
if((fp=fopen("test.bmp","rb"))==NULL)
{
printf("Fail to Open bmp File!\n");
exit(0);
}
fseek(fp,54,SEEK_SET); //跳过bmp文件头
for(n=0;n<800*480;n++) { fread(mptr++,1,1,fp); fread(mptr++,1,1,fp); fread(mptr++,1,1,fp); mptr++; } fclose(fp); munmap(mptr,800*480*4); close(fd_dev); return 0; }

使用OpenGL ES

OpenGL ES是一种针对移动设备的OpenGL版本。相比于桌面版本,它放弃了许多功能,以提高性能和降低功耗。 OpenGL ES的应用场景包括游戏、嵌入式应用、虚拟现实和图形界面等。以下是在Linux开发板上显示图片的OpenGL ES示例代码:


#include
#include

#include
#include

#define IMG_WIDTH 800
#define IMG_HEIGHT 600
#define IMG_HORIZ_ALIGNMENT 64

struct Image {
GLuint tex;
GLfloat uv[2][2];
unsigned int width;
unsigned int height;
unsigned char *data;
};

static void
create_texture(struct Image *img)
{
glGenTextures(1, &img->tex);
glBindTexture(GL_TEXTURE_2D, img->tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
img->width, img->height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, img->data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
}

static void
draw_img(EGLDisplay dpy, EGLSurface surf, struct Image *img)
{
static const GLfloat verts[][2] = {
{ -1.0, -1.0 },
{ -1.0, +1.0 },
{ +1.0, +1.0 },
{ +1.0, -1.0 },
};
static const GLfloat uv[2][2] = {
{ 0.0, 0.0 },
{ 1.0, 0.0 },
{ 1.0, 1.0 },
{ 0.0, 1.0 },
};
static const GLushort indices[] = {
0, 1, 2,
0, 2, 3,
};

glClear(GL_COLOR_BUFFER_BIT);

glUseProgram(prog);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, img->tex);

glUniformMatrix4fv(unif_texm, 1, GL_FALSE, (GLfloat *)tex_mat);
glUniformMatrix4fv(unif_projm, 1, GL_FALSE, (GLfloat *)proj_mat);

glEnableVertexAttribArray(attr_vertpos);
glEnableVertexAttribArray(attr_texcoord);
glVertexAttribPointer(attr_vertpos, 2, GL_FLOAT, GL_FALSE, 0, verts);
glVertexAttribPointer(attr_texcoord, 2, GL_FLOAT, GL_FALSE, 0, img->uv);

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);

glDisableVertexAttribArray(attr_vertpos);
glDisableVertexAttribArray(attr_texcoord);

eglSwapBuffers(dpy, surf);
}

static void
init_egl(EGLDisplay *dpy, EGLContext *ctx, EGLSurface *surf,
int width, int height)
{
const EGLint attr[] = {
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_BUFFER_SIZE, 32,
EGL_DEPTH_SIZE, 0,
EGL_STENCIL_SIZE, 0,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NONE,
};
const EGLint ctx_attr[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE,
};
const EGLint surf_attr[] = {
EGL_NONE,
};
EGLConfig egl_conf;
EGLint num_confs;
EGLContext egl_ctx;
EGLSurface egl_surf;

*dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(*dpy, NULL, NULL);

eglChooseConfig(*dpy, attr, &egl_conf, 1, &num_confs);
if (num_confs <= 0) { fprintf(stderr, "Failed to get EGLConfig.\n"); exit(EXIT_FAILURE); } egl_ctx = eglCreateContext(*dpy, egl_conf, NULL, ctx_attr); if (egl_ctx == NULL) { fprintf(stderr, "Failed to create EGL context.\n"); exit(EXIT_FAILURE); } egl_surf = eglCreateWindowSurface(*dpy, egl_conf, NULL, surf_attr); if (egl_surf == NULL) { fprintf(stderr, "Failed to create EGL surface.\n"); exit(EXIT_FAILURE); } eglMakeCurrent(*dpy, egl_surf, egl_surf, egl_ctx); glViewport(0, 0, width, height);}intmain(int argc, char *argv[]){ static const GLfloat tex_mat[] = { 1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, }; static const GLfloat proj_mat[] = { 2.0, 0.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 0.0, 2.0, 0.0, -1.0, -1.0, 0.0, 1.0, }; static const char *vert_src = "attribute vec4 pos;\n" "attribute vec2 texcoord;\n" "\n" "uniform mat4 texm;\n" "uniform mat4 projm;\n" "\n" "varying vec2 texcoord_f;\n" "\n" "void main() {\n" " texcoord_f = (vec4(texcoord, 0, 1) * texm).xy;\n" " gl_Position = pos * projm;\n" "}\n"; static const char *frag_src = "precision mediump float;\n" "\n" "uniform sampler2D tex;\n" "\n" "varying vec2 texcoord_f;\n" "\n" "void main() {\n" " gl_FragColor = texture2D(tex, texcoord_f);\n" "}\n"; char *buf; int fd; struct Image img; int pitch; EGLDisplay egl_dpy; EGLContext egl_ctx; EGLSurface egl_surf; int ret; if (argc < 2) { fprintf(stderr, "Usage: %s FILE\n", argv[0]); exit(EXIT_FAILURE); } fd = open(argv[1], O_RDONLY); if (fd < 0) { perror("open"); exit(EXIT_FAILURE); } buf = malloc(IMG_HEIGHT * IMG_HORIZ_ALIGNMENT * 4); img.data = malloc(IMG_WIDTH * IMG_HEIGHT * 4); if (buf == NULL || img.data == NULL) { fprintf(stderr, "Failed to allocate memory.\n"); exit(EXIT_FAILURE); } ret = read(fd, buf, IMG_HEIGHT * IMG_HORIZ_ALIGNMENT * 4); if (ret != IMG_HEIGHT * IMG_HORIZ_ALIGNMENT * 4) { perror("read"); exit(EXIT_FAILURE); } for (int y = 0; y < IMG_HEIGHT; y++) { memcpy(&img.data[y * IMG_WIDTH * 4], &buf[y * IMG_HORIZ_ALIGNMENT * 4], IMG_WIDTH * 4); } close(fd); img.width = IMG_WIDTH; img.height = IMG_HEIGHT; create_texture(&img); pitch = img.width * 4; if (pitch & 0x1f) pitch = (pitch + 0x1f) & ~0x1f; EGLint w, h; w = IMG_WIDTH; h = IMG_HEIGHT; // Initialize EGL init_egl(&egl_dpy, &egl_ctx, &egl_surf, w, h); // kernel routine draw_img(egl_dpy, egl_surf, &img); if (prod) { //capture_screen(); } // Release resources glDeleteTextures(1, &img.tex); eglDestroySurface(egl_dpy, egl_surf); eglDestroyContext(egl_dpy, egl_ctx); eglTerminate(egl_dpy); free(buf); free(img.data); return 0;}

结论

Framebuffer和OpenGL ES都能够实现在Linux开发板上显示图片。前者适用于嵌入式系统对硬件要求较低、使用成熟的Linux图形库的情况。后者适用于更为灵活的开发和图形处理,但对性能和功耗有一定要求。通过选择合适的开发工具和主板,我们可以实现高品质的显示效果,满足各种应用需求。

本文来自投稿,不代表亲测学习网立场,如若转载,请注明出处:https://www.qince.net/arm-m1q.html

郑重声明:

本站所有内容均由互联网收集整理、网友上传,并且以计算机技术研究交流为目的,仅供大家参考、学习,不存在任何商业目的与商业用途。 若您需要商业运营或用于其他商业活动,请您购买正版授权并合法使用。

我们不承担任何技术及版权问题,且不对任何资源负法律责任。

如遇到资源无法下载,请点击这里失效报错。失效报错提交后记得查看你的留言信息,24小时之内反馈信息。

如有侵犯您的版权,请给我们私信,我们会尽快处理,并诚恳的向你道歉!

(0)
上一篇 2023年5月1日 下午3:19
下一篇 2023年5月1日 下午3:19

猜你喜欢