图像格式转换之BMP格式转换为JPG格式

时间:2021-10-05 06:35:52
  1 // bmp2jpg.cpp : 定义控制台应用程序的入口点。
  2 //
  3 #include "stdafx.h"
  4 #include "jpeglib.h"
  5 #include "stdlib.h"
  6 #pragma comment(lib,"libjpeg.lib")
  7 #pragma pack(4)        //两字节对齐,否则bmp_fileheader会占16Byte
  8 
  9 /*图像bmp格式文件头结构*/
 10 struct bmp_fileheader
 11 {
 12     unsigned short    bfType;        //若不对齐,这个会占4Byte
 13     unsigned long     bfSize;
 14     unsigned short    bfReverved1;
 15     unsigned short    bfReverved2;
 16     unsigned long     bfOffBits;
 17 };
 18 
 19 /*图像bmp格式信息头结构*/
 20 struct bmp_infoheader
 21 {
 22     unsigned long    biSize;
 23     unsigned long    biWidth;
 24     unsigned long    biHeight;
 25     unsigned short   biPlanes;
 26     unsigned short   biBitCount;
 27     unsigned long    biCompression;
 28     unsigned long    biSizeImage;
 29     unsigned long    biXPelsPerMeter;
 30     unsigned long    biYpelsPerMeter;
 31     unsigned long    biClrUsed;
 32     unsigned long    biClrImportant;
 33 };
 34 
 35 FILE *input_file ; //输入bmp文件指针
 36 FILE *output_file; //输出jpg文件指针
 37 bmp_fileheader bmpFh;
 38 bmp_infoheader bmpIh;
 39 
 40 unsigned char *src_buffer;
 41 unsigned char *dst_buffer;
 42 
 43 /*读取图像bmp文件头结构*/
 44 void readBmpHeader()
 45 {    
 46     /*读取输入bmp格式图像文件头*/
 47     fread(&bmpFh , sizeof(bmp_fileheader) , 1 , input_file);
 48 
 49     /*读取输入bmp格式图像信息头*/
 50     fread(&bmpIh , sizeof(bmp_infoheader), 1 , input_file);
 51 }
 52 
 53 /*读取图像bmp数据*/
 54 void readBmpData()
 55 {
 56     fseek(input_file , bmpFh.bfOffBits,SEEK_SET);
 57     src_buffer = (unsigned char *)malloc(sizeof(unsigned char)*bmpIh.biWidth*bmpIh.biHeight*bmpIh.biBitCount/8);
 58     if(NULL == src_buffer)
 59     {
 60         printf("malloc memory failed!\n");
 61         return ;
 62     }
 63 
 64     fread(src_buffer , sizeof(unsigned char)*bmpIh.biWidth*bmpIh.biHeight*bmpIh.biBitCount/8,1 , input_file);
 65 
 66     /*将bmp数据读取到目标huffbuffer*/
 67     unsigned long width = bmpIh.biWidth ; 
 68     unsigned long height= bmpIh.biHeight ;
 69     unsigned short depth= bmpIh.biBitCount/8 ;
 70     unsigned char *src_point ; 
 71     unsigned char *dst_point ;
 72     unsigned long i = 0 ;
 73     unsigned long j = 0 ;
 74     unsigned long rgb_index = 0 ;
 75 
 76     dst_buffer = (unsigned char *)malloc(sizeof(unsigned char)*width*height*depth);
 77     if(NULL == dst_buffer)
 78     {
 79         printf("malloc memory failed!\n");
 80         return ;
 81     }
 82 
 83     src_point  = src_buffer + width*depth*(height-1);
 84     dst_point  = dst_buffer + width*depth*(height-1);
 85 
 86     for(i = 0 ; i < height ; i++)
 87     {
 88         for(j = 0 ; j < width*depth ; j+=depth)
 89         {
 90             if(depth == 1)
 91             {
 92                 dst_point[j] = src_point[j];  
 93             }
 94 
 95             if(depth == 3)
 96             {
 97                 dst_point[j+2]=src_point[j+0];
 98 
 99                 dst_point[j+1]=src_point[j+1];
100 
101                 dst_point[j+0]=src_point[j+2];
102             }
103             
104         }
105 
106         dst_point -= width*depth ;
107         src_point -= width*depth ;
108     }
109 }
110 
111 void synthese_jpeg()
112 {
113     struct jpeg_compress_struct cinfo;
114     struct jpeg_error_mgr jerr;
115     JSAMPARRAY buffer;
116 
117     unsigned long width=bmpIh.biWidth;
118     unsigned long height=bmpIh.biHeight;
119     unsigned short depth=bmpIh.biBitCount/8;
120     unsigned char *point;
121     cinfo.err=jpeg_std_error(&jerr);        //libjpeg各种配置
122     jpeg_create_compress(&cinfo);
123     jpeg_stdio_dest(&cinfo,output_file);
124     cinfo.image_width=width;
125     cinfo.image_height=height;
126     cinfo.input_components=depth;
127     if (depth==1)
128         cinfo.in_color_space=JCS_GRAYSCALE;
129     else
130         cinfo.in_color_space=JCS_RGB;
131 
132     jpeg_set_defaults(&cinfo);
133     jpeg_set_quality(&cinfo,20,TRUE);    //中间的值为压缩质量,越大质量越好
134     jpeg_start_compress(&cinfo,TRUE);
135 
136     buffer=(*cinfo.mem->alloc_sarray)
137             ((j_common_ptr)&cinfo,JPOOL_IMAGE,width*depth,1);
138     point=dst_buffer+width*depth*(height-1);
139     while (cinfo.next_scanline<height)
140     {
141         memcpy(*buffer,point,width*depth);
142         jpeg_write_scanlines(&cinfo,buffer,1);
143         point-=width*depth;
144     }
145 
146     jpeg_finish_compress(&cinfo);
147     jpeg_destroy_compress(&cinfo);
148 }
149 
150 int main()
151 {
152     input_file=fopen("E:/test_pic.bmp","rb");
153     if(NULL == input_file)
154     {
155         printf("open input file failed!\n");
156     }
157     output_file=fopen("E:/save_pic.jpg","wb");
158     if(NULL == output_file)
159     {
160         printf("open output file failed!\n");
161     }
162 
163     readBmpHeader();
164     readBmpData();
165     synthese_jpeg();
166     fclose(input_file);
167     fclose(output_file);
168 
169     free(src_buffer);
170     free(dst_buffer);
171 
172     return 0;
173 }