一、libjpeg移植
libjpeg 下载 http://www.ijg.org/files/. 选择一个版本。尽量选择新的版本,但不建议选最新版本。
1. 解压 tar -xvf jpegsrc.v9b.tar.gz
2. 解压后进入生成新目录,进入目录jpeg-9b
3. 对libjpeg 工程进行配置 ./configure --host=arm-linux-gnueabihf --prefix=/opt/i.mx/thirdparty/libjpeg_so
4. make & make install
5. 这时再libjpeg_so 会生成如下几个文件bin, include, lib ,share 表示移植编译成功
6. 移植:把 libjpeg_so 的 bin 拷贝到开发板的/usr/bin lib 拷贝到开发板的/usr/lib include 拷贝到/usr/include
7. 验证,再开发板直接运行 djpeg -h 能出现以下信息即可。
libjpeg 使用:
使用libjpeg库,只需包含头文件 jpeglib.h 即可。
libjepg 的重要api。
1. jpeg_std_error(&jerr);
2. //创建解码对象
jpeg_create_decompress(&cinfo);
3. //指定图像信息
jpeg_stdio_src(&cinfo,fp);
4.//读取图像信息
jpeg_read_header(&cinfo,TRUE);
5.设置图片缩放比例
cinfo.scale_num = 1;
cinfo.scale_denom = 2;
6. //设置解码参数开始解码
cinfo.out_color_space = JCS_RGB;
jpeg_start_decompress(&cinfo);
7. 开始逐行解码,解码进度可以通过cinfo.output_scanline 来判断,cinfo.output_height可以得知输出图像尺寸。输入图像数据为 BGR888
jpeg_read_scanlines(&cinfo,(unsigned char**)&jpeg_line_buff,1);
8. 解码结束
jpeg_finish_decompress(&cinfo);
9. 销毁解码对象
jpeg_destroy_decompress(&cinfo);
二、libpng移植
libpng 需要依赖与zlib 库。 png 图像是无损压缩图像,用于取代gif格式图像。支持动态静态图像。
移植libpng库前需要先移植zlib库。zlib库移植比较简单,https://www.zlib.net/fossils/ 可以下载到zlib库
下载完后解压,配置,编译,安装即可。配置命令:./configure --prefix=/opt/i.mx/thirdparty/libzlib_so
libpng移植:
官方下载地址:Releases · glennrp/libpng · GitHub
1. 下载后解压:tar -xvf libpng-1.6.35.tar.gz
2. 解压后进入目录 libpng-1.6.35
3. 配置,libpng 不能通过./configure 指定 zlib 的路径,虽然./configure 有提供 --with-zlib-prefix 选项。可以通过输入以下3个命令
export LDFLAGS="${LDFLAGS} -L/opt/i.mx/thirdparty/libzlib_so/lib"
export CFLAGS="${CFLAGS} -I/opt/i.mx/thirdparty/libzlib_so/include"
export CPPFLAGS="${CPPFLAGS} -I/opt/i.mx/thirdparty/libzlib_so/include"
./configure --prefix=/opt/i.mx/thirdparty/libpng_so/ --host=arm-linux-gnueabihf
4. make & make install
5. 把生成的/libpng_so/bin libpng_so/include/ libpng_so/lib 分别拷贝到开发板的 /usr/bin /usr/include /usr/lib 中。
6. 测试 执行 pngfix -h 能执行成功,表示移植成功。
libpng 重要的api函数和应用
int read_png_image(char *fname,unsigned char **imgdata,int *w,int *h) { png_structp png_ptr = NULL; png_infop info_ptr = NULL; unsigned int imgw = 0,imgh = 0,i,row_bytes = 0; png_bytepp row_pointers = NULL; unsigned char bitdep = 0,color_type = 0; FILE *fp = NULL; fp = fopen(fname,"r"); if(fp == NULL){ printf("open %s failed\n",fname); return -1; } png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL); if(png_ptr == NULL){ fclose(fp); return -2; } info_ptr = png_create_info_struct(png_ptr); if(info_ptr == NULL){ png_destroy_read_struct(&png_ptr,NULL,NULL); fclose(fp); return -2; } //设置错误返回点 if(setjmp(png_jmpbuf(png_ptr))){ png_destroy_read_struct(&png_ptr,NULL,NULL); fclose(fp); return -3; } //指定数据源 png_init_io(png_ptr,fp); //读取png文件 png_read_png(png_ptr,info_ptr,(PNG_TRANSFORM_STRIP_16|PNG_TRANSFORM_BGR|PNG_TRANSFORM_EXPAND|PNG_TRANSFORM_PACKING),NULL); imgw = png_get_image_width(png_ptr,info_ptr); imgh = png_get_image_height(png_ptr,info_ptr); printf("image size: %d * %d \n",imgw,imgh); //判断png数据,是不是RGB888 bitdep = png_get_channels(png_ptr,info_ptr); // printf("channel count: %d\n",bitdep); bitdep = png_get_bit_depth(png_ptr,info_ptr); color_type = png_get_color_type(png_ptr,info_ptr); // printf("bit depth: %d color_type:%d \n",bitdep,color_type); if(bitdep != 8||(color_type != PNG_COLOR_TYPE_RGB)){ printf("error image is not RGB888 !\n"); png_destroy_read_struct(&png_ptr,&info_ptr,NULL); fclose(fp); return -4; } // png_set_sCAL(png_ptr,info_ptr,1,255.0,140.0); //不清楚该函数用处 // imgw = png_get_image_width(png_ptr,info_ptr); // imgh = png_get_image_height(png_ptr,info_ptr); // printf("image size: %d * %d \n",imgw,imgh); //读取解码后的数据 row_bytes = png_get_rowbytes(png_ptr,info_ptr); row_pointers = png_get_rows(png_ptr,info_ptr); *imgdata = (unsigned char*)malloc(imgw*imgh*3); // imgh = 2; for(i = 0;i < imgh;i++){ memcpy(*(imgdata) + (row_bytes * i),row_pointers[i],row_bytes); } *w = imgw; *h = imgh; //结束、销毁/释放内存 png_destroy_read_struct(&png_ptr,&info_ptr,NULL); fclose(fp); return 0; } int lcd_show_rgbimage(unsigned short x,unsigned short y,unsigned short w,unsigned short h,unsigned char *imgdata) { short i = 0,j = 0; int off = 0,idx = 0; if(x + w > lcd_width){ return -1; } if(y + h > lcd_width){ return -2; } off = y * lcd_width + x; // printf("off = %d w = %d h = %d\n",off,w,h); for(j = 0;j < h;j ++){ for(i = 0;i < w;i ++){ // B G R *(unsigned int*)(pFrambuff + off + i) = imgdata[idx] | imgdata[idx+1] << 8 | imgdata[idx+2] << 16; idx += 3; } off += lcd_width; } return 0; } int lcd_display_png(unsigned short x,unsigned short y,char *fname,lcd_align_t align) { int w = 0,h = 0,ret = 0; unsigned char *imgdata = NULL; ret = read_png_image(fname,&imgdata,&w,&h); if(ret != 0){ return ret; } if(align == align_center){ x = (lcd_width - w)/2; y = (lcd_height - h)/2; } printf("lcd_show_rgbimage\n"); lcd_show_rgbimage(x,y,w,h,imgdata); free(imgdata); return 0; }