Jpeglib读取jpg文件

来源:互联网 发布:淘宝店商品下架上架 编辑:程序博客网 时间:2024/05/16 04:56

整理自:

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就行了

2.项目中引入库
将编译出来的lib目录和lib名称配置到VC的linker中,头文件引入就可以了。

3.实例代码(Jpeglib读取图像函数说明见代码注释)

[cpp] view plain copy
 print?
  1. //// JEPGFile.cpp : Defines the entry point for the console application.  
  2. ////  
  3. //  
  4. #include "stdafx.h"  
  5. #include <stdio.h>  
  6. #include <string.h>  
  7. #include <stdlib.h>  
  8. #include "jpeglib.h"  
  9.   
  10. #define PUT_2B(array,offset,value)  \  
  11.          (array[offset] = (char) ((value) & 0xFF), \  
  12.           array[offset+1] = (char) (((value) >> 8) & 0xFF))  
  13.  #define PUT_4B(array,offset,value)  \  
  14.          (array[offset] = (char) ((value) & 0xFF), \  
  15.           array[offset+1] = (char) (((value) >> 8) & 0xFF), \  
  16.           array[offset+2] = (char) (((value) >> 16) & 0xFF), \  
  17.           array[offset+3] = (char) (((value) >> 24) & 0xFF))  
  18.   
  19.  void write_bmp_header(j_decompress_ptr cinfo, FILE *output_file)  
  20.  {  
  21.          //cinfo已经转换为小端模式了     
  22.          char bmpfileheader[14];  
  23.          char bmpinfoheader[40];  
  24.          long headersize, bfSize;  
  25.          int bits_per_pixel, cmap_entries;  
  26.   
  27.   
  28.          int step;  
  29.   
  30.          /* Compute colormap size and total file size */  
  31.          if (cinfo->out_color_space == JCS_RGB) {  
  32.                  if (cinfo->quantize_colors) {  
  33.                          /* Colormapped RGB */  
  34.                          bits_per_pixel = 8;  
  35.                          cmap_entries = 256;  
  36.                  } else {  
  37.                          /* Unquantized, full color RGB */  
  38.                          bits_per_pixel = 24;  
  39.                          cmap_entries = 0;  
  40.                  }  
  41.          } else {  
  42.                  /* Grayscale output.  We need to fake a 256-entry colormap. */  
  43.                  bits_per_pixel = 8;  
  44.                  cmap_entries = 256;  
  45.          }  
  46.   
  47.          step = cinfo->output_width * cinfo->output_components;  
  48.   
  49.          while ((step & 3) != 0) step++;  
  50.   
  51.          /* File size */  
  52.          headersize = 14 + 40 + cmap_entries * 4; /* Header and colormap */  
  53.   
  54.         bfSize = headersize + (long) step * (long) cinfo->output_height;  
  55.   
  56.          /* Set unused fields of header to 0 */  
  57.          memset(bmpfileheader, 0, sizeof(bmpfileheader));  
  58.          memset(bmpinfoheader, 0 ,sizeof(bmpinfoheader));  
  59.   
  60.          /* Fill the file header */  
  61.          bmpfileheader[0] = 0x42;/* first 2 bytes are ASCII 'B', 'M' */  
  62.          bmpfileheader[1] = 0x4D;  
  63.          PUT_4B(bmpfileheader, 2, bfSize); /* bfSize */  
  64.          /* we leave bfReserved1 & bfReserved2 = 0 */  
  65.          PUT_4B(bmpfileheader, 10, headersize); /* bfOffBits */  
  66.   
  67.          /* Fill the info header (Microsoft calls this a BITMAPINFOHEADER) */  
  68.          PUT_2B(bmpinfoheader, 0, 40);   /* biSize */  
  69.          PUT_4B(bmpinfoheader, 4, cinfo->output_width); /* biWidth */  
  70.          PUT_4B(bmpinfoheader, 8, cinfo->output_height); /* biHeight */  
  71.          PUT_2B(bmpinfoheader, 12, 1);   /* biPlanes - must be 1 */  
  72.          PUT_2B(bmpinfoheader, 14, bits_per_pixel); /* biBitCount */  
  73.          /* we leave biCompression = 0, for none */  
  74.          /* we leave biSizeImage = 0; this is correct for uncompressed data */  
  75.          if (cinfo->density_unit == 2) { /* if have density in dots/cm, then */  
  76.                  PUT_4B(bmpinfoheader, 24, (INT32) (cinfo->X_density*100)); /* XPels/M */  
  77.                  PUT_4B(bmpinfoheader, 28, (INT32) (cinfo->Y_density*100)); /* XPels/M */  
  78.          }  
  79.          PUT_2B(bmpinfoheader, 32, cmap_entries); /* biClrUsed */  
  80.          /* we leave biClrImportant = 0 */  
  81.   
  82.          if (fwrite(bmpfileheader, 1, 14, output_file) != (size_t) 14) {  
  83.                  printf("write bmpfileheader error\n");  
  84.          }  
  85.          if (fwrite(bmpinfoheader, 1, 40, output_file) != (size_t) 40) {  
  86.                  printf("write bmpinfoheader error\n");  
  87.          }  
  88.   
  89.          if (cmap_entries > 0) {  
  90.          }  
  91.  }  
  92.   
  93.  void write_pixel_data(j_decompress_ptr cinfo, unsigned char *output_buffer, FILE *output_file)  
  94.  {  
  95.          int rows, cols;  
  96.          int row_width;  
  97.          int step;  
  98.          unsigned char *tmp = NULL;  
  99.   
  100.         unsigned char *pdata;  
  101.   
  102.          row_width = cinfo->output_width * cinfo->output_components;  
  103.          step = row_width;  
  104.          while ((step & 3) != 0) step++;  
  105.   
  106.          pdata = (unsigned char *)malloc(step);  
  107.          memset(pdata, 0, step);  
  108.   
  109.          // JPEG左上角的开始一行行写的数据,转换为BMP的从左下角开始一行行写的数据  
  110.          // 也就是JPEG最末的行放置到BMP最开始行,JPEG最开始行放置到BMP最末行就对了。  
  111.          tmp = output_buffer + row_width * (cinfo->output_height - 1);  
  112.          for (rows = 0; rows < cinfo->output_height; rows++) {  
  113.                  for (cols = 0; cols < row_width; cols += 3) {  
  114.                         // 大端模式转换为小端模式  
  115.                          pdata[cols + 2] = tmp[cols + 0];  
  116.                          pdata[cols + 1] = tmp[cols + 1];  
  117.                          pdata[cols + 0] = tmp[cols + 2];  
  118.                  }  
  119.                  tmp -= row_width;  
  120.                  fwrite(pdata, 1, step, output_file);  
  121.          }  
  122.   
  123.          free(pdata);  
  124.  }  
  125.   
  126.   
  127.  /*读JPEG文件相当于解压文件*/  
  128.   
  129.  int read_jpeg_file(const char *input_filename, const char *output_filename)  
  130.  {  
  131.          struct jpeg_decompress_struct cinfo;  
  132.          struct jpeg_error_mgr jerr;  
  133.          FILE *input_file;  
  134.          FILE *output_file;  
  135.          JSAMPARRAY buffer;  
  136.          int row_width;  
  137.   
  138.          unsigned char *output_buffer;  
  139.          unsigned char *tmp = NULL;  
  140.   
  141.          cinfo.err = jpeg_std_error(&jerr);  
  142.   
  143.          if ((input_file = fopen(input_filename, "rb")) == NULL) {  
  144.                  fprintf(stderr, "can't open %s\n", input_filename);  
  145.                  return -1;  
  146.          }  
  147.   
  148.          if ((output_file = fopen(output_filename, "wb")) == NULL) {  
  149.   
  150.                 fprintf(stderr, "can't open %s\n", output_filename);  
  151.                  return -1;  
  152.          }  
  153.   
  154.          // Initialization of JPEG compression objects  
  155.          jpeg_create_decompress(&cinfo);  
  156.   
  157.          /* Specify data source for decompression */  
  158.          jpeg_stdio_src(&cinfo, input_file);  
  159.   
  160.          /* 1.设置读取jpg文件头部,Read file header, set default decompression parameters */  
  161.          (void) jpeg_read_header(&cinfo, TRUE);  
  162.   
  163.          /* 2.开始解码数据 Start decompressor */  
  164.          (void) jpeg_start_decompress(&cinfo);  
  165.   
  166.          row_width = cinfo.output_width * cinfo.output_components;  
  167.   
  168.          /* 3.跳过读取的头文件字节Make a one-row-high sample array that will go away when done with image */  
  169.          buffer = (*cinfo.mem->alloc_sarray)  
  170.                  ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_width, 1);  
  171.   
  172.          write_bmp_header(&cinfo, output_file);  
  173.   
  174.          output_buffer = (unsigned char *)malloc(row_width * cinfo.output_height);  
  175.          memset(output_buffer, 0, row_width * cinfo.output_height);  
  176.          tmp = output_buffer;  
  177.   
  178.          /* 4.Process data由左上角从上到下行行扫描 */  
  179.          while (cinfo.output_scanline < cinfo.output_height) {  
  180.                  (void) jpeg_read_scanlines(&cinfo, buffer, 1);  
  181.   
  182.                  memcpy(tmp, *buffer, row_width);  
  183.                  tmp += row_width;  
  184.          }  
  185.   
  186.         // 写入数据,注意大小端转换和图像数据坐标表示差异在内存中的顺序          
  187.          write_pixel_data(&cinfo, output_buffer, output_file);  
  188.   
  189.          free(output_buffer);  
  190.   
  191.          (void) jpeg_finish_decompress(&cinfo);  
  192.   
  193.          jpeg_destroy_decompress(&cinfo);  
  194.   
  195.          /* Close files, if we opened them */  
  196.          fclose(input_file);  
  197.          fclose(output_file);  
  198.   
  199.         return 0;  
  200.  }  
  201.   
  202.   
  203. int write_jpeg_file(char * filename, int quality)  
  204. {  
  205.   
  206.   struct jpeg_compress_struct cinfo;  
  207.   unsigned char  * image_buffer;  
  208.   int i = 0;  
  209.   struct jpeg_error_mgr jerr;  
  210.   /* More stuff */  
  211.   FILE * outfile;  /* target file */  
  212.   JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */  
  213.   int row_stride;  /* physical row width in image buffer */  
  214.   
  215.   /* Step 1: allocate and initialize JPEG compression object */  
  216.   
  217.   /* We have to set up the error handler first, in case the initialization 
  218.    * step fails.  (Unlikely, but it could happen if you are out of memory.) 
  219.    * This routine fills in the contents of struct jerr, and returns jerr's 
  220.    * address which we place into the link field in cinfo. 
  221.    */  
  222.    /*1.第一步创建jpeg compress 对象*/  
  223.   cinfo.err = jpeg_std_error(&jerr);  
  224.   /* Now we can initialize the JPEG compression object. */  
  225.   jpeg_create_compress(&cinfo);  
  226.   
  227.   /* Step 2: specify data destination (eg, a file) */  
  228.   /* Note: steps 2 and 3 can be done in either order. */  
  229.   
  230.   /* Here we use the library-supplied code to send compressed data to a 
  231.    * stdio stream. You can also write your own code to do something else. 
  232.    * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that 
  233.    * requires it in order to write binary files. 
  234.    */  
  235.    /*写的方式打开文件*/  
  236.   if ((outfile = fopen(filename, "wb")) == NULL) {  
  237.  fprintf(stderr, "can't open %s\n", filename);  
  238.  exit(1);  
  239.   }  
  240.   jpeg_stdio_dest(&cinfo, outfile);  
  241.   
  242.   /* Step 3: set parameters for compression */  
  243.   
  244.   /* First we supply a description of the input image. 
  245.    * Four fields of the cinfo struct must be filled in: 
  246.    */  
  247.    /*2.设置 压缩参数 libjpeg中的宽度和高度是两个全局的 
  248.   我这默认设置成640 480。根据demo中的说明color_space必须 
  249.   得设置*/  
  250.   cinfo.image_width = 640; /* image width and height, in pixels */  
  251.   cinfo.image_height = 480;  
  252.   cinfo.input_components = 3;  /* # of color components per pixel */  
  253.   cinfo.in_color_space = JCS_RGB; /* colorspace of input image */  
  254.   /* Now use the library's routine to set default compression parameters. 
  255.    * (You must set at least cinfo.in_color_space before calling this, 
  256.    * since the defaults depend on the source color space.) 
  257.    */  
  258.   jpeg_set_defaults(&cinfo);  
  259.   /* Now you can set any non-default parameters you wish to. 
  260.    * Here we just illustrate the use of quality (quantization table) scaling: 
  261.    */  
  262.    /*设置quality为2*/  
  263.   jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);  
  264.   
  265.   /* Step 4: Start compressor */  
  266.   
  267.   /* TRUE ensures that we will write a complete interchange-JPEG file. 
  268.    * Pass TRUE unless you are very sure of what you're doing. 
  269.    */  
  270.    /*3. 开始压缩*/  
  271.   jpeg_start_compress(&cinfo, TRUE);  
  272.   
  273.   /* Step 5: while (scan lines remain to be written) */  
  274.   /*     jpeg_write_scanlines(...); */  
  275.   
  276.   /* Here we use the library's state variable cinfo.next_scanline as the 
  277.    * loop counter, so that we don't have to keep track ourselves. 
  278.    * To keep things simple, we pass one scanline per call; you can pass 
  279.    * more if you wish, though. 
  280.    */  
  281.   row_stride = 640 * 3; /* JSAMPLEs per row in image_buffer */  
  282.  image_buffer = (unsigned char*)malloc(640*480*3);  
  283.   
  284.  if (NULL == image_buffer)  
  285.  {  
  286.   return -1;  
  287.  }  
  288.  for(i=0; i< 640*480; i++)  
  289.    {  
  290.      // 4.构造的数据,数据是RGB形式Pixel  
  291.      image_buffer[i*3] = 255/*i*255*/;  
  292.      image_buffer[i*3+1] = 255/*128-(i*255)&0x7f*/;  
  293.      image_buffer[i*3+2] = 0/*255-(i*255)&0xff*/;  
  294.    }  
  295.   
  296.   while (cinfo.next_scanline < cinfo.image_height) {  
  297.  /* jpeg_write_scanlines expects an array of pointers to scanlines. 
  298.   * Here the array is only one element long, but you could pass 
  299.   * more than one scanline at a time if that's more convenient. 
  300.   */  
  301.  // 5.将数据扫描输入,image_buffer数据是RGB形式Pixel  
  302.  row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];  
  303.  (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);  
  304.   }  
  305.   
  306.   /* Step 6: Finish compression */  
  307.   // 6.完成压缩  
  308.   jpeg_finish_compress(&cinfo);  
  309.   /* After finish_compress, we can close the output file. */  
  310.   fclose(outfile);  
  311.   
  312.   /* Step 7: release JPEG compression object */  
  313.   
  314.   /* This is an important step since it will release a good deal of memory. */  
  315.   jpeg_destroy_compress(&cinfo);  
  316.   
  317.   /* And we're done! */  
  318. }  
  319.   
  320.   
  321.  int main(int argc, char *argv[])  
  322.  {        
  323.      read_jpeg_file("f:\\data\\animal.jpg""f:\\data\\animal.bmp");  
  324.      write_jpeg_file("f:\\data\\createJpg.jpg", 2);  
  325.      
  326.      return 0;  
  327.  }  
  328.   
  329.    
0 0