zoukankan      html  css  js  c++  java
  • Jpeglib读取jpg文件

    整理自:

    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读取图像函数说明见代码注释)

    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 ");  
    84.          }  
    85.          if (fwrite(bmpinfoheader, 1, 40, output_file) != (size_t) 40) {  
    86.                  printf("write bmpinfoheader error ");  
    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 ", input_filename);  
    145.                  return -1;  
    146.          }  
    147.   
    148.          if ((output_file = fopen(output_filename, "wb")) == NULL) {  
    149.   
    150.                 fprintf(stderr, "can't open %s ", 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 ", 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.    
  • 相关阅读:
    LeetCode 258 Add Digits
    LeetCode 231 Power of Two
    LeetCode 28 Implement strStr()
    LeetCode 26 Remove Duplicates from Sorted Array
    LeetCode 21 Merge Two Sorted Lists
    LeetCode 20 Valid Parentheses
    图形处理函数库 ImageTTFBBox
    php一些函数
    func_get_arg(),func_get_args()和func_num_args()的用法
    人生不是故事,人生是世故,摸爬滚打才不会辜负功名尘土
  • 原文地址:https://www.cnblogs.com/huty/p/8518922.html
Copyright © 2011-2022 走看看