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 }