1、背景、
有时候在项目中需要用到底层c语言去读取图像像素值,移植opencv中的imread函数,涉及到图片的编解码,以及其他的函数,使得项目开展十分麻烦,所以我们可以借助第三方库来实现像素值的读取操作。
2、libjpeg下载,编译
下载地址:这里
There is a Windows format package in zip archive format jpegsr9d.zip and a Unix format package in tar.gz archive format jpegsrc.v9d.tar.gz,根据需要选择。
1、./configure#配置
2、make#编译
3、make install#默认安装到/usr/local/lib/下,所以在编译时记得指定链接库地址
3、使用libjpeg
#include <stdio.h>
#include <stdlib.h>
#include <jpeglib.h>
/*
* Descr: 读取jpeg文件的data内容(取出文件头信息)
* @param input_filename :jpeg文件路径(含文件名)输入
* @param output_buffer :返回指向数据地址的指针
* @param
* @Author :Libin
* @return :成功返回0,失败返回-1
*/
int read_jpeg_file(const char *input_filename, char **output_buffer)
{
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE *input_file;
FILE *output_file;
JSAMPARRAY buffer;
int row_width;
unsigned char *rowdata = NULL;
cinfo.err = jpeg_std_error(&jerr);
if ((input_file = fopen(input_filename, "rb")) == NULL) {
fprintf(stderr, "can't open %s\n", input_filename);
return -1;
}
// 1、Initialization of JPEG compression objects
jpeg_create_decompress(&cinfo);
/* Specify data source for decompression */
jpeg_stdio_src(&cinfo, input_file);
/* 1.设置读取jpg文件头部,Read file header, set default decompression parameters */
(void) jpeg_read_header(&cinfo, TRUE);
/* 2.开始解码数据 Start decompressor */
(void) jpeg_start_decompress(&cinfo);
row_width = cinfo.output_width * cinfo.output_components;
/* 3.跳过读取的头文件字节Make a one-row-high sample array that will go away when done with image */
buffer = (*cinfo.mem->alloc_sarray)
((j_common_ptr) &cinfo, JPOOL_IMAGE, row_width, 1);
printf("Get image width:%d,height:%d\n",row_width,cinfo.output_height);
*output_buffer = (unsigned char *)malloc(row_width * cinfo.output_height);
memset(*output_buffer, 0, row_width * cinfo.output_height);
rowdata = *output_buffer;
/* 4.Process data由左上角从上到下行行扫描 */
while (cinfo.output_scanline < cinfo.output_height) {
(void) jpeg_read_scanlines(&cinfo, buffer, 1);
memcpy(rowdata, *buffer, row_width);
rowdata += row_width;
}
//free(output_buffer);
(void) jpeg_finish_decompress(&cinfo);
printf("Get iamge data ,buffer size=%d\n",strlen((const char* ) *output_buffer));
jpeg_destroy_decompress(&cinfo);
/* Close files, if we opened them */
fclose(input_file);
return 0;
}
int main()
{
const char* input_filename="/home/libin/Code/jpeg-9/testimgp.jpg";
char *outbuffer=NULL;
read_jpeg_file(input_filename,&outbuffer);
printf("Get iamge data ,buffer size=%d\n",strlen((const char* ) outbuffer));
free(outbuffer);//释放malloc的地址,否则可能造成内存泄漏
return 0;
}
编译时可以自己写一个简单的makefile。例如:
CC = gcc
CFLAGS = -g -Wall -O
LIBJPEGLIBS = -L/usr/local/lib/ -ljpeg
main:main.o
$(CC) decodejpeg.o -o decodejpeg $(LIBJPEGLIBS)
main.o:decodejpeg.c
$(CC) $(CFLAGS) -c decodejpeg.c
clean:
rm -rf ./*.o decodejpeg
在当前目录下会生成可执行文件。