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.    
  • 相关阅读:
    mysql同步 小问题
    通过 XtraBackup 实现不停机不锁表搭建主从同步
    grep -A -B选项详解和mysqlbinlog
    MySQL存储过程中的3种循环
    mysql利用存储过程批量插入数据
    React routerV4 笔记
    数据结构算法基础定义
    网站性能优化
    去重除了indexOf的其他方法(使用对象Key的方法)及统计重复次数
    立即执行函数的两种写法及闭包
  • 原文地址:https://www.cnblogs.com/huty/p/8518921.html
Copyright © 2011-2022 走看看