当前位置: 首页 > 嵌入式Linux > 正文

使用libjpeg库在LCD上显示图片

背景:
网上已经有很多关于利用libjpeg显示图片的文章了,因此本文的技术含量不算高。本文是使用libjpeg的v8版本,在开发板的LCD上显示jpg格式图片,关于libjpeg,可到其官方网站下载源码,源码附有许多文档,包括详细的例子(example.c)。
关于如何使用libjpeg,本文不再说明,因为网上文章已经很多了。本文中的代码有几处是自已经修改过的。
1、将所有操作framebuffer的函数放到单独的文件,名称为fb_utils.c,代码主要是来自一个叫ripple的项目。这个文件也用到其它很多地方。
2、libjpeg指定的图片来源有两种,一是文件,一是内存。后者是新版本支持的,旧版本,例如6b,就没有这个函数。

完整的显示jpg图片函数如下:

/*** draw_jpeg – Display a jpeg picture from (0, 0) on framebuffer

* @name: picture name(foo.jpg)

*/

int draw_jpeg(char *name)

{

struct jpeg_decompress_struct cinfo;

struct jpeg_error_mgr jerr;

FILE *infile;

unsigned char  *buffer;

int x, y;        unsigned char *tmp_buf;

unsigned long size;

int ret;

if ((infile = fopen(name, “rb”)) == NULL) {

fprintf(stderr, “open %s failedn”, name);

return -1;

}

cinfo.err = jpeg_std_error(&jerr);

jpeg_create_decompress(&cinfo);

// 获取图片文件大小

fseek(infile, 0L, SEEK_END);

size = ftell(infile);

rewind(infile);

tmp_buf = (unsigned char *)malloc(sizeof(char) * size);

if (tmp_buf == NULL)

{

printf(“malloc failed.n”);

return -1;

}

ret = fread(tmp_buf, 1, size, infile);

if (ret != size)

{

printf(“read jpeg file error.n”);

return -1;

}

// memory

jpeg_mem_src(&cinfo, tmp_buf, size);        // 指定图片在内存的地址及大小

//jpeg_stdio_src(&cinfo, infile); // 指定图片文件

jpeg_read_header(&cinfo, TRUE);

jpeg_start_decompress(&cinfo);

if ((cinfo.output_width > fb_width) || (cinfo.output_height > fb_height)) {

printf(“too large JPEG file,cannot displayn”);

return -1;

}

buffer = (unsigned char *) malloc(cinfo.output_width * cinfo.output_components);

//printf(“%d %dn”, cinfo.output_width, cinfo.output_components); /*eg, 240 3(rgb888)*/

x = y = 0;

while (cinfo.output_scanline < cinfo.output_height) {

jpeg_read_scanlines(&cinfo, &buffer, 1);

if (fb_depth == 16) {

unsigned short  color;

for (x=0; x < cinfo.output_width; x++) {

// LCD为rgb565格式

color = make16color(buffer[x*3], buffer[x*3+1], buffer[x*3+2]);

fb_pixel(x, y, color);

}

else if (fb_depth == 24) {

// not test

memcpy((unsigned char *) fb_mem + y * fb_width * 3,

buffer, cinfo.output_width * cinfo.output_components);

}

y++;        // next scanline

}

jpeg_finish_decompress(&cinfo);

jpeg_destroy_decompress(&cinfo);

fclose(infile);

free(tmp_buf);

free(buffer);

return 0;

}

几点说明:
1、使用图片文件测试,第一种是用jpeg_stdio_src指定图片来源为文件,第二种是将图片读入内存,再使用jpeg_mem_src来指定图片在内存的位置及大小。
2、本文测试所用的LCD格式为rgb565,即16色,而原来图片为24色,所以需要使用一个函数来转换。当得到适合在LCD显示的颜色值后,就可以调用像素函数在LCD上画点了。
就这么简单。

下面是在LCD上显示的图片,使用fb2png截图。

 

左图是rgb565格式,因为LCD就是这种格式,显示正常,而右图是rgb888格式,不能正常显示出来。

关于fb2png这个工具,我找了好久,现在已经不记得原代码出处了。可以到

http://download.csdn.net/detail/subfate/3345143下载,如果没有CSDN的积分,请到

http://www.latelee.org/yetanothertest/tools/下载。

rgb565格式的图片rgb888格式的图片
完整的工程及测试用的图片压缩包下载:

http://www.latelee.org/yetanothertest/program/src/jpeg-test-latelee.org.tar.bz2

注:压缩包中的fb_utils.c文件在不断修改,当修改后,恕不更新此处的工程。

本文固定链接: http://www.latelee.org/embedded-linux/display-picture-on-lcd-using-libjpeg.html

如无特别说明,迟思堂工作室文章均为原创,转载请注明: 使用libjpeg库在LCD上显示图片 | 迟思堂工作室

目前暂无评论

发表评论

*

快捷键:Ctrl+Enter