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 }