RGB24转jpeg

   我的摄像头不支持直接取jpeg图片,读取的原始数据是YUYV格式,要在内存中转换成RGB24后,再存为jpeg图片。可以到www.ijg.org网站下载libjpeg的源码。
 
一、准备工作
   下载好源码之后编译之后可以得到libjpeg的静态链接库(.a)和动态链接库(.so),如图:
    
   使用的时候把源代码里面的jconfig.h,jmorecfg.h,jpeglib.h这三个文件放到自己项目的路径下,在自己的程序里面添加头文件,#include  “jpeglib.h” 。编译的时候添加一下你刚刚编译得到的库文件libjpeg.so和libjpeg.so.9.1.0的路径即可。要注意不同的运行环境需要不同的编译器,如果是arm中运行,就需要指定交叉编译工具。
 
1. PC下编译libjpeg
   先解压tar xvfz jpegsrc.v9a.tar.gz,解压得到的源码里面有一个install.txt介绍说如果是UNIX系统就只需要:
   #./configure
   #make
   #make test (test是用来自检验是否安装成功的)
   #make install 
   我按照此步骤安装之后没找到库文件的位置,就自己指定路径重新编译了一下。
   #./configure --prefix=/usr/local/jpeg --enable-shared--enable-static
 
2. 使用arm-linux-gcc来交叉编译arm环境中的libjpeg
   #./configure --prefix=/opt/Cubieboard/jpeg  --host=arm-linuxCC=arm-linux-gnueabihf-gcc --enable-shared --enable-static
   #make
   #make install
   参数--enable-shared --enable-static 对静态链接库和动态链接库都支持。linux库文件分为静态库和动态库两种。静态库习惯以.a 结尾,而动态库习惯以.so(shared object)结尾。而且必须以lib开头。
http://blog.chinaunix.net/uid-22125732-id-1790604.html
 
二、 jpeg压缩步骤
   压缩和解压缩步骤:
 
  
int save_rgb_to_jpg(char *soureceData, int imgWidth, int imgHeight, char * fileName)
{
	int depth = 3;//1 for gray, 3 for color
	struct jpeg_compress_struct cinfo;
	struct jpeg_error_mgr jerr;
	FILE *outfile;                 
	JSAMPROW row_pointer[1];        // pointer to JSAMPLE row[s] 
	int row_stride = imgWidth;      // physical row width in image buffer 

	cinfo.err = jpeg_std_error(&jerr);
	jpeg_create_compress(&cinfo);

	if ((outfile = fopen(fileName, "wb")) == NULL)
	{
		fprintf(stderr, "can't open %s\n", fileName);
		return -1;
	}
	jpeg_stdio_dest(&cinfo, outfile);

	cinfo.image_width = imgWidth;      // image width and height, in pixels 
	cinfo.image_height = imgHeight;
	cinfo.input_components = depth;    // of color components per pixel 
	cinfo.in_color_space = JCS_RGB;    //or JCS_GRAYSCALE;   colorspace of input image 

	jpeg_set_defaults(&cinfo);
	jpeg_set_quality(&cinfo, JPEG_QUALITY, TRUE ); /* limit to baseline-JPEG values */

	jpeg_start_compress(&cinfo, TRUE);

	row_stride = imgWidth; /* JSAMPLEs per row in image_buffer */

	while (cinfo.next_scanline < cinfo.image_height) 
	{
		row_pointer[0] = & soureceData[cinfo.next_scanline * row_stride*depth];
		(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
	}

	jpeg_finish_compress(&cinfo);
	jpeg_destroy_compress(&cinfo);	
	fclose(outfile);

	return 0;
}

http://blog.itpub.net/7232789/viewspace-714150/
http://blog.csdn.net/limingshandian/article/details/7751300
 
三、编译自己的工程
   #arm-linux-gnueabihf-gcc -o myjpg myjpg.c -L/usr/local/jpeg/lib-ljpeg -Wl,-rpath,/usr/local/jpeg/lib
 
   -L是指定编译时链接库的路径。-ljpeg指定编译时的链接库名称,在链接时候,加上选项-l后接库文件名,注意:必须是文件名去掉后缀和lib。不加-L则编译器默认在/lib和/usr/lib路径下寻找,当然,编译器会告诉你“找不到XXX.so”。
   -Wl,-rpath,/usr/local/jpeg/lib这三个用逗号隔开的参数是告诉ld执行的时候到该路径下寻找库。最开始我没有加上这个参数,编译的时候没有出错,但是执行的时候提示ld找不到XXX.so。
   使用ldd查看链接库的路径,如:
   #ldd myjpg
可以看到目标文件的链接库的路径
http://blog.sina.com.cn/s/blog_690c46500100kxhd.html
 
四、遇到的问题
1.  jpg的文件名中不能有冒号。
   这个让我排查了好久。最初我是在开发板上,插上U盘,想直接把文件写到U盘中(/mnt/usb下),一开始还以为不能直接写到U盘。觉得开发板调试太慢,就把程序放到host中去调试,那么问题就来了,U盘插上去以后,自动在/media/下生成一个目录/D48D-12AB,于是我就直接写入/media//D48D-12AB下,又失败了。
2. 不能直接写或者cp来操作/media/ D48D-12AB中的文件。
   就是说这个路径下你只能通过鼠标右键的方式进行操作。

你可能感兴趣的:(嵌入式)