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 structbmp_fileheader11 {12 unsigned short bfType; //若不对齐,这个会占4Byte
13 unsigned longbfSize;14 unsigned shortbfReverved1;15 unsigned shortbfReverved2;16 unsigned longbfOffBits;17 };18
19 /*图像bmp格式信息头结构*/
20 structbmp_infoheader21 {22 unsigned longbiSize;23 unsigned longbiWidth;24 unsigned longbiHeight;25 unsigned shortbiPlanes;26 unsigned shortbiBitCount;27 unsigned longbiCompression;28 unsigned longbiSizeImage;29 unsigned longbiXPelsPerMeter;30 unsigned longbiYpelsPerMeter;31 unsigned longbiClrUsed;32 unsigned longbiClrImportant;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 voidreadBmpHeader()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 voidreadBmpData()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 voidsynthese_jpeg()112 {113 structjpeg_compress_struct cinfo;114 structjpeg_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
146 jpeg_finish_compress(&cinfo);147 jpeg_destroy_compress(&cinfo);148 }149
150 intmain()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 }