整理自:
https://blog.youkuaiyun.com/ice__snow/article/details/52563944
http://blog.youkuaiyun.com/mcgrady_tracy/article/details/7439066
用libjpeg库读取jpeg文件
,官网链接:http://libjpeg.sourceforge.net/,下载链接:http://www.ijg.org/files/。
本文件使用的是9c这个版本。
---------------------------------------------------------------------------------------------------------------------------------------------
一、编译出libjpeg.lib文件
1. 下载并解压
2. 找到jconfig.cv,复制并改名为jconfig.h
3. 找到makefile.vc这个文件,打开(随便一个文本编辑器)找到这一行
把路径改为win32.mk
在你电脑上的路径,每个人的可能不太一样,路径差别可能不是很大,我的是C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Include\win32.mak
,改为
4. 准备编译,从VS的工具点击“Visual Studio 命令提示”进入控制台
5. 进入jpeg-9c的目录,输入编译命令开始编译
命令:nmake -f makefile.vc
6. 编译后在目录下找到库libjpeg.lib
就编译成功了。
二、使用
具体的使用在目录下的example.c中有,注释非常细,看了基本就会用了。
1. 配置
在VS中配置libjpeg.lib,配置方法略
2. 使用
程序里包含头文件#include "jpeglib.h"
就行了。
大部分照搬,细节可以看里面的英语注释,主要的几个地方修改下就行了,看下面的汉语注释:
/*读JPEG文件相当于解压文件*/
int read_jpeg_file(const char *input_filename, const 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 *output_buffer;
unsigned char *tmp = 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;
}
// 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);
output_buffer = (unsigned char *)malloc(row_width * cinfo.output_height);
memset(output_buffer, 0, row_width * cinfo.output_height);
tmp = output_buffer;
/* 4.Process data由左上角从上到下行行扫描 */
while (cinfo.output_scanline < cinfo.output_height) {
(void) jpeg_read_scanlines(&cinfo, buffer, 1);
memcpy(tmp, *buffer, row_width);
tmp += row_width;
}
//free(output_buffer);
(void) jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
/* Close files, if we opened them */
fclose(input_file);
fclose(output_file);
return 0;
}
也可以将代码中的第4步中
……
memcpy(tmp, *buffer, row_width);
tmp += row_width;
……
替换为
// 在这里添加代码获取到图片的像素数据
// buffer保存了读取的当前行的数据,保存顺序是RGB
// output_scanline是已经读取过的行数
// img.create(cinfo.image_height, cinfo.image_width, 3); //放在while外
for (int i = 0; i < img.cols; ++i) {
img[cinfo.output_scanline - 1][i * 3 + 2] = buffer[0][i * 3 + 0];
img[cinfo.output_scanline - 1][i * 3 + 1] = buffer[0][i * 3 + 1];
img[cinfo.output_scanline - 1][i * 3 + 0] = buffer[0][i * 3 + 2];
}