jpg转bmp(使用libjpeg)
生活随笔
收集整理的這篇文章主要介紹了
jpg转bmp(使用libjpeg)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
還是關于圖像格式上的東西。使用了libjpeg庫將jpeg圖像轉換到bmp格式。解壓原理還是相對復雜的,將來有機會說不定會詳細介紹。這里只是庫的使用而已。
首先需要下載libjpeg庫,網址在這里:http://www.ijg.org/
然后需要配置環境,我是在windows下用vs2010搞的,編譯庫可以參考這篇文章。編譯出jpeg.lib就可以了。當然實際編程還需要相應的頭文件,頭文件在下載的文件中。
如果不想編譯就在這下載吧:http://vdisk.weibo.com/s/jpiMs
下面是相應的例程,只能將24位彩色圖和8位深度圖的jpg轉換到bmp。
#include <iostream>
#include <stdio.h>
extern "C"{
#include "jpeglib.h"
};
#pragma comment(lib,"jpeg.lib")
using namespace std;
#pragma pack(2) //兩字節對齊,否則bmp_fileheader會占16Byte
struct bmp_fileheader
{
unsigned short bfType; //若不對齊,這個會占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));
//寫入比較關鍵的幾個bmp頭參數
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) //灰度圖像要添加調色板
{
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); //倒著寫數據,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函數,具體參看相關文檔
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圖像數據到buffer
memcpy(point,*buffer,width*depth); //將buffer中的數據逐行給src_buff
point+=width*depth; //一次改變一行
}
write_bmp_header(&cinfo); //寫bmp文件頭
write_bmp_data(&cinfo,src_buff); //寫bmp像素數據
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()有內存泄露,不想在源代碼上編輯了。
總結
以上是生活随笔為你收集整理的jpg转bmp(使用libjpeg)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 平面镜成像的原理是什么
- 下一篇: 有诗意的追星文案 守护爱豆的句子131个