這篇文章對(duì)使用libjpeg有一個(gè)比較好的引導(dǎo)作用,雖然測(cè)試,程序有一定的問題,但不影響問題的說明。可以到這里下載一個(gè)實(shí)例程序,已經(jīng)調(diào)通了。另外貢獻(xiàn)自己根據(jù)例程修改得到的cdib程序,可以使mfc對(duì)jpeg圖片進(jìn)行相關(guān)的顯示和處理。jpg轉(zhuǎn)bmp(使用libjpeg)還是關(guān)于圖像格式上的東西。使用了libjpeg庫(kù)將jpeg圖像轉(zhuǎn)換到bmp格式。解壓原理還是相對(duì)復(fù)雜的,將來有機(jī)會(huì)說不定會(huì)詳細(xì)介紹。這里只是庫(kù)的使用而已。 首先需要下載libjpeg庫(kù),網(wǎng)址在這里:http://www./ 然后需要配置環(huán)境,我是在windows下用vs2010搞的,編譯庫(kù)可以參考這篇文章。編譯出jpeg.lib就可以了。當(dāng)然實(shí)際編程還需要相應(yīng)的頭文件,頭文件在下載的文件中。 如果不想編譯就在這下載吧:http://vdisk.weibo.com/s/jpiMs 下面是相應(yīng)的例程,只能將24位彩色圖和8位深度圖的jpg轉(zhuǎn)換到bmp。 #include <iostream> #include <stdio.h> extern "C"{ #include "jpeglib.h" }; #pragma comment(lib,"jpeg.lib") using namespace std; #pragma pack(2) //兩字節(jié)對(duì)齊,否則bmp_fileheader會(huì)占16Byte struct bmp_fileheader { unsigned short bfType; //若不對(duì)齊,這個(gè)會(huì)占4Byte unsigned long bfSize; unsigned short bfReverved1; unsigned short bfReverved2; unsigned long bfOffBits; }; struct bmp_infoheader { unsigned long biSize; unsigned long biWidth; unsigned long biHeight; unsigned short biPlanes; unsigned short biBitCount; unsigned long biCompression; unsigned long biSizeImage; unsigned long biXPelsPerMeter; unsigned long biYpelsPerMeter; unsigned long biClrUsed; unsigned long biClrImportant; }; FILE *input_file; FILE *output_file; void write_bmp_header(j_decompress_ptr cinfo) { struct bmp_fileheader bfh; struct bmp_infoheader bih; unsigned long width; unsigned long height; unsigned short depth; unsigned long headersize; unsigned long filesize; width=cinfo->output_width; height=cinfo->output_height; depth=cinfo->output_components; if (depth==1) { headersize=14+40+256*4; filesize=headersize+width*height; } if (depth==3) { headersize=14+40; filesize=headersize+width*height*depth; } memset(&bfh,0,sizeof(struct bmp_fileheader)); memset(&bih,0,sizeof(struct bmp_infoheader)); //寫入比較關(guān)鍵的幾個(gè)bmp頭參數(shù) bfh.bfType=0x4D42; bfh.bfSize=filesize; bfh.bfOffBits=headersize; bih.biSize=40; bih.biWidth=width; bih.biHeight=height; bih.biPlanes=1; bih.biBitCount=(unsigned short)depth*8; bih.biSizeImage=width*height*depth; fwrite(&bfh,sizeof(struct bmp_fileheader),1,output_file); fwrite(&bih,sizeof(struct bmp_infoheader),1,output_file); if (depth==1) //灰度圖像要添加調(diào)色板 { unsigned char *platte; platte=new unsigned char[256*4]; unsigned char j=0; for (int i=0;i<1024;i+=4) { platte[i]=j; platte[i+1]=j; platte[i+2]=j; platte[i+3]=0; j++; } fwrite(platte,sizeof(unsigned char)*1024,1,output_file); delete[] platte; } } void write_bmp_data(j_decompress_ptr cinfo,unsigned char *src_buff) { unsigned char *dst_width_buff; unsigned char *point; unsigned long width; unsigned long height; unsigned short depth; width=cinfo->output_width; height=cinfo->output_height; depth=cinfo->output_components; dst_width_buff=new unsigned char[width*depth]; memset(dst_width_buff,0,sizeof(unsigned char)*width*depth); point=src_buff+width*depth*(height-1); //倒著寫數(shù)據(jù),bmp格式是倒的,jpg是正的 for (unsigned long i=0;i<height;i++) { for (unsigned long j=0;j<width*depth;j+=depth) { if (depth==1) //處理灰度圖 { dst_width_buff[j]=point[j]; } if (depth==3) //處理彩色圖 { dst_width_buff[j+2]=point[j+0]; dst_width_buff[j+1]=point[j+1]; dst_width_buff[j+0]=point[j+2]; } } point-=width*depth; fwrite(dst_width_buff,sizeof(unsigned char)*width*depth,1,output_file); //一次寫一行 } } void analyse_jpeg() { struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; JSAMPARRAY buffer; unsigned char *src_buff; unsigned char *point; cinfo.err=jpeg_std_error(&jerr); //一下為libjpeg函數(shù),具體參看相關(guān)文檔 jpeg_create_decompress(&cinfo); jpeg_stdio_src(&cinfo,input_file); jpeg_read_header(&cinfo,TRUE); jpeg_start_decompress(&cinfo); unsigned long width=cinfo.output_width; unsigned long height=cinfo.output_height; unsigned short depth=cinfo.output_components; src_buff=new unsigned char[width*height*depth]; memset(src_buff,0,sizeof(unsigned char)*width*height*depth); buffer=(*cinfo.mem->alloc_sarray) ((j_common_ptr)&cinfo,JPOOL_IMAGE,width*depth,1); point=src_buff; while (cinfo.output_scanline<height) { jpeg_read_scanlines(&cinfo,buffer,1); //讀取一行jpg圖像數(shù)據(jù)到buffer memcpy(point,*buffer,width*depth); //將buffer中的數(shù)據(jù)逐行給src_buff point+=width*depth; //一次改變一行 } write_bmp_header(&cinfo); //寫bmp文件頭 write_bmp_data(&cinfo,src_buff); //寫bmp像素?cái)?shù)據(jù) jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); delete[] src_buff; } int main() { input_file=fopen("lena.jpg","rb"); output_file=fopen("lena.bmp","wb"); analyse_jpeg(); fclose(input_file); fclose(output_file); cout<<"good job."<<endl; cin.get(); return 0; } 注:write_bmp_data()有內(nèi)存泄露,不想在源代碼上編輯了。
分類: 格式分析 |
|