Jpeglib读取jpg文件 【转】
http://blog.csdn.net/blues1021/article/details/45424695
整理自 :
http://hi.baidu.com/lewutian/item/e8eed42664ee61122a0f1c89
http://blog.csdn.net/mcgrady_tracy/article/details/7439066
1 . 下载编译库
下载库:
http://www.ijg.org/ 网址下面的windows版本的。本文下载的是jpegsr9a.zip。
编译库:
libjpeg,以vs2008为例, 首先要把jconfig.vc复制为jconfig.h。
打开VS2008的command line prompt命令行提示符,切换到解压的libjpeg目录下,输入"nmake -f makefile.vc"
完成后取出libjpeg.lib就行了
- //// JEPGFile.cpp : Defines the entry point for the console application.
- ////
- //
- #include "stdafx.h"
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include "jpeglib.h"
- #define PUT_2B(array,offset,value) \
- (array[offset] = (char) ((value) & 0xFF), \
- array[offset+1] = (char) (((value) >> 8) & 0xFF))
- #define PUT_4B(array,offset,value) \
- (array[offset] = (char) ((value) & 0xFF), \
- array[offset+1] = (char) (((value) >> 8) & 0xFF), \
- array[offset+2] = (char) (((value) >> 16) & 0xFF), \
- array[offset+3] = (char) (((value) >> 24) & 0xFF))
- void write_bmp_header(j_decompress_ptr cinfo, FILE *output_file)
- {
- //cinfo已经转换为小端模式了
- char bmpfileheader[14];
- char bmpinfoheader[40];
- long headersize, bfSize;
- int bits_per_pixel, cmap_entries;
- int step;
- /* Compute colormap size and total file size */
- if (cinfo->out_color_space == JCS_RGB) {
- if (cinfo->quantize_colors) {
- /* Colormapped RGB */
- bits_per_pixel = 8;
- cmap_entries = 256;
- } else {
- /* Unquantized, full color RGB */
- bits_per_pixel = 24;
- cmap_entries = 0;
- }
- } else {
- /* Grayscale output. We need to fake a 256-entry colormap. */
- bits_per_pixel = 8;
- cmap_entries = 256;
- }
- step = cinfo->output_width * cinfo->output_components;
- while ((step & 3) != 0) step++;
- /* File size */
- headersize = 14 + 40 + cmap_entries * 4; /* Header and colormap */
- bfSize = headersize + (long) step * (long) cinfo->output_height;
- /* Set unused fields of header to 0 */
- memset(bmpfileheader, 0, sizeof(bmpfileheader));
- memset(bmpinfoheader, 0 ,sizeof(bmpinfoheader));
- /* Fill the file header */
- bmpfileheader[0] = 0x42;/* first 2 bytes are ASCII 'B', 'M' */
- bmpfileheader[1] = 0x4D;
- PUT_4B(bmpfileheader, 2, bfSize); /* bfSize */
- /* we leave bfReserved1 & bfReserved2 = 0 */
- PUT_4B(bmpfileheader, 10, headersize); /* bfOffBits */
- /* Fill the info header (Microsoft calls this a BITMAPINFOHEADER) */
- PUT_2B(bmpinfoheader, 0, 40); /* biSize */
- PUT_4B(bmpinfoheader, 4, cinfo->output_width); /* biWidth */
- PUT_4B(bmpinfoheader, 8, cinfo->output_height); /* biHeight */
- PUT_2B(bmpinfoheader, 12, 1); /* biPlanes - must be 1 */
- PUT_2B(bmpinfoheader, 14, bits_per_pixel); /* biBitCount */
- /* we leave biCompression = 0, for none */
- /* we leave biSizeImage = 0; this is correct for uncompressed data */
- if (cinfo->density_unit == 2) { /* if have density in dots/cm, then */
- PUT_4B(bmpinfoheader, 24, (INT32) (cinfo->X_density*100)); /* XPels/M */
- PUT_4B(bmpinfoheader, 28, (INT32) (cinfo->Y_density*100)); /* XPels/M */
- }
- PUT_2B(bmpinfoheader, 32, cmap_entries); /* biClrUsed */
- /* we leave biClrImportant = 0 */
- if (fwrite(bmpfileheader, 1, 14, output_file) != (size_t) 14) {
- printf("write bmpfileheader error\n");
- }
- if (fwrite(bmpinfoheader, 1, 40, output_file) != (size_t) 40) {
- printf("write bmpinfoheader error\n");
- }
- if (cmap_entries > 0) {
- }
- }
- void write_pixel_data(j_decompress_ptr cinfo, unsigned char *output_buffer, FILE *output_file)
- {
- int rows, cols;
- int row_width;
- int step;
- unsigned char *tmp = NULL;
- unsigned char *pdata;
- row_width = cinfo->output_width * cinfo->output_components;
- step = row_width;
- while ((step & 3) != 0) step++;
- pdata = (unsigned char *)malloc(step);
- memset(pdata, 0, step);
- // JPEG左上角的开始一行行写的数据,转换为BMP的从左下角开始一行行写的数据
- // 也就是JPEG最末的行放置到BMP最开始行,JPEG最开始行放置到BMP最末行就对了。
- tmp = output_buffer + row_width * (cinfo->output_height - 1);
- for (rows = 0; rows < cinfo->output_height; rows++) {
- for (cols = 0; cols < row_width; cols += 3) {
- // 大端模式转换为小端模式
- pdata[cols + 2] = tmp[cols + 0];
- pdata[cols + 1] = tmp[cols + 1];
- pdata[cols + 0] = tmp[cols + 2];
- }
- tmp -= row_width;
- fwrite(pdata, 1, step, output_file);
- }
- free(pdata);
- }
- /*读JPEG文件相当于解压文件*/
- int read_jpeg_file(const char *input_filename, const char *output_filename)
- {
- 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;
- }
- if ((output_file = fopen(output_filename, "wb")) == NULL) {
- fprintf(stderr, "can't open %s\n", output_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);
- write_bmp_header(&cinfo, output_file);
- 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;
- }
- // 写入数据,注意大小端转换和图像数据坐标表示差异在内存中的顺序
- write_pixel_data(&cinfo, output_buffer, output_file);
- 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;
- }
- int write_jpeg_file(char * filename, int quality)
- {
- struct jpeg_compress_struct cinfo;
- unsigned char * image_buffer;
- int i = 0;
- struct jpeg_error_mgr jerr;
- /* More stuff */
- FILE * outfile; /* target file */
- JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
- int row_stride; /* physical row width in image buffer */
- /* Step 1: allocate and initialize JPEG compression object */
- /* We have to set up the error handler first, in case the initialization
- * step fails. (Unlikely, but it could happen if you are out of memory.)
- * This routine fills in the contents of struct jerr, and returns jerr's
- * address which we place into the link field in cinfo.
- */
- /*1.第一步创建jpeg compress 对象*/
- cinfo.err = jpeg_std_error(&jerr);
- /* Now we can initialize the JPEG compression object. */
- jpeg_create_compress(&cinfo);
- /* Step 2: specify data destination (eg, a file) */
- /* Note: steps 2 and 3 can be done in either order. */
- /* Here we use the library-supplied code to send compressed data to a
- * stdio stream. You can also write your own code to do something else.
- * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
- * requires it in order to write binary files.
- */
- /*写的方式打开文件*/
- if ((outfile = fopen(filename, "wb")) == NULL) {
- fprintf(stderr, "can't open %s\n", filename);
- exit(1);
- }
- jpeg_stdio_dest(&cinfo, outfile);
- /* Step 3: set parameters for compression */
- /* First we supply a description of the input image.
- * Four fields of the cinfo struct must be filled in:
- */
- /*2.设置 压缩参数 libjpeg中的宽度和高度是两个全局的
- 我这默认设置成640 480。根据demo中的说明color_space必须
- 得设置*/
- cinfo.image_width = 640; /* image width and height, in pixels */
- cinfo.image_height = 480;
- cinfo.input_components = 3; /* # of color components per pixel */
- cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
- /* Now use the library's routine to set default compression parameters.
- * (You must set at least cinfo.in_color_space before calling this,
- * since the defaults depend on the source color space.)
- */
- jpeg_set_defaults(&cinfo);
- /* Now you can set any non-default parameters you wish to.
- * Here we just illustrate the use of quality (quantization table) scaling:
- */
- /*设置quality为2*/
- jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
- /* Step 4: Start compressor */
- /* TRUE ensures that we will write a complete interchange-JPEG file.
- * Pass TRUE unless you are very sure of what you're doing.
- */
- /*3. 开始压缩*/
- jpeg_start_compress(&cinfo, TRUE);
- /* Step 5: while (scan lines remain to be written) */
- /* jpeg_write_scanlines(...); */
- /* Here we use the library's state variable cinfo.next_scanline as the
- * loop counter, so that we don't have to keep track ourselves.
- * To keep things simple, we pass one scanline per call; you can pass
- * more if you wish, though.
- */
- row_stride = 640 * 3; /* JSAMPLEs per row in image_buffer */
- image_buffer = (unsigned char*)malloc(640*480*3);
- if (NULL == image_buffer)
- {
- return -1;
- }
- for(i=0; i< 640*480; i++)
- {
- // 4.构造的数据,数据是RGB形式Pixel
- image_buffer[i*3] = 255/*i*255*/;
- image_buffer[i*3+1] = 255/*128-(i*255)&0x7f*/;
- image_buffer[i*3+2] = 0/*255-(i*255)&0xff*/;
- }
- while (cinfo.next_scanline < cinfo.image_height) {
- /* jpeg_write_scanlines expects an array of pointers to scanlines.
- * Here the array is only one element long, but you could pass
- * more than one scanline at a time if that's more convenient.
- */
- // 5.将数据扫描输入,image_buffer数据是RGB形式Pixel
- row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
- (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
- }
- /* Step 6: Finish compression */
- // 6.完成压缩
- jpeg_finish_compress(&cinfo);
- /* After finish_compress, we can close the output file. */
- fclose(outfile);
- /* Step 7: release JPEG compression object */
- /* This is an important step since it will release a good deal of memory. */
- jpeg_destroy_compress(&cinfo);
- /* And we're done! */
- }
- int main(int argc, char *argv[])
- {
- read_jpeg_file("f:\\data\\animal.jpg", "f:\\data\\animal.bmp");
- write_jpeg_file("f:\\data\\createJpg.jpg", 2);
- return 0;
- }
Jpeglib读取jpg文件 【转】的更多相关文章
- Jpeglib读取jpg文件
整理自: http://hi.baidu.com/lewutian/item/e8eed42664ee61122a0f1c89 http://blog.csdn.net/mcgrady_tracy/a ...
- Unity3D移动平台动态读取外部文件全解析
前言: 一直有个想法,就是把工作中遇到的坑通过自己的深挖,总结成一套相同问题的解决方案供各位同行拍砖探讨.眼瞅着2015年第一个工作日就要来到了,小匹夫也休息的差不多了,寻思着也该写点东西活动活动大脑 ...
- python读取caffemodel文件
caffemodel是二进制的protobuf文件,利用protobuf的python接口可以读取它,解析出需要的内容 不少算法都是用预训练模型在自己数据上微调,即加载"caffemodel ...
- informatica读取FTP文件
以下为一个完整的informatica读取ftp文件,并导入到系统中. 第一步: 通过shell脚本下载压缩包文件 /server/infa_shared/crm_prod/shell/ftpFrom ...
- Java读取word文件,字体,颜色
在Android读取Word文件时,在网上查看时可以用tm-extractors,但好像没有提到怎么读取Word文档中字体的颜色,字体,上下标等相关的属性.但由于需要,要把doc文档中的内容(字体,下 ...
- 五种方式让你在java中读取properties文件内容不再是难题
一.背景 最近,在项目开发的过程中,遇到需要在properties文件中定义一些自定义的变量,以供java程序动态的读取,修改变量,不再需要修改代码的问题.就借此机会把Spring+SpringMVC ...
- Javascript写入txt和读取txt文件的方法
文章主要介绍了Javascript写入txt和读取txt文件的方法,需要的朋友可以参考下1. 写入 FileSystemObject可以将文件翻译成文件流. 第一步: 例: 复制代码 代码如下: Va ...
- .NET 读取本地文件绑定到GridViewRow
wjgl.aspx.cs: using System; using System.Collections; using System.Configuration; using System.Data; ...
- sparkR读取csv文件
sparkR读取csv文件 The general method for creating SparkDataFrames from data sources is read.df. This met ...
随机推荐
- hdu 2444(染色法判断二分图+最大匹配)
The Accomodation of Students Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K ( ...
- 配置文件中的mime-mapping元素(ofbiz/framework/catalina/config/mime-type)(
mime-mapping元素将mime类型映射到扩展名. extension元素用来描述扩展名.mime-type元素则为MIME类型. <?xml version="1.0" ...
- laravel中新增路由文件
随着业务的发展,前后台和不同平台的代码都写在一个路由文件里面会非常庞杂,这时候就诞生了拆分路由文件的需求,好在Lavravel给我们提供了支持: 1.在routes文件夹中添加新的路由文件如:admi ...
- ASOP编译说明
具体说明https://source.android.com/source/ 源码下载https://mirrors.tuna.tsinghua.edu.cn/help/AOSP/ 1 搭建编译环境使 ...
- 【cocos2d-js教程】cocos2d-js 遮挡层(禁止触摸事件传递层)
在游戏中,我们经常会碰到一些弹窗,这些弹窗禁止点透,也就是禁止触摸事件传递到底层,我们称之为遮挡层,这些遮挡层,需要开发遮挡层,我们首先得了解cocos2d-js的触摸传递机制,本文主要针对cocos ...
- 【BFS】【余数剪枝】Multiple
[poj1465]Multiple Time Limit: 1000MS Memory Limit: 32768K Total Submissions: 7731 Accepted: 1723 ...
- [ARC062F]Painting Graphs with AtCoDeer
题意:一个无向图,用$k$种不同的颜色给每条边染色,问能染出多少种不同的图,如果两张图能通过循环移位环边使得颜色相同,那么这两张图被认为是相同的 数学太差伤不起啊...补了一下Burnside定理的证 ...
- 【最小割】【Dinic】Gym - 101201G - Maximum Islands
题意:方格内有些位置是水域,有些位置是陆地,有些位置是被云彩遮挡住了:让你自己规定被云彩遮挡住的地方是陆地还是水域,使得陆地个数最多.(均为四连通块) 显然与陆地邻接的云彩填成水比较优.其他云彩格子填 ...
- 【BFS】bzoj2252 [2010Beijing wc]矩阵距离
要注意一开始将所有为'1'的点入队,然后通过一次BFS去更新所有点的距离,直到无法更新为止. #include<cstdio> #include<queue> #include ...
- 【贪心+优先队列】POJ3190-Stall Reservations
[题目大意] 给出每个奶牛挤奶的时间,同一时间同一畜栏内不会有两头奶牛挤奶,问至少要多少个畜栏. [思路] 将奶牛按照挤奶开始的时间进行升序排序,再用一个小顶堆维护每一个畜栏当前的挤奶结束时间.对于当 ...