您的位置:首页 > 其它

bmp转jpg(使用libjpeg)

2015-04-07 14:43 351 查看
转自:http://www.cnblogs.com/tiandsp/archive/2012/12/03/2799561.html

pg压缩原理可以参考这篇文章http://hi.baidu.com/tiandsp/item/f5a2dcde6ef1405bd73aae41,我很早以前转的一篇文章。

  没有使用libjpeg的压缩代码可以看看这篇文章http://hi.baidu.com/tiandsp/item/9b5843c58a3b4474cfd4f841,也是我很早以前转的。

  这次使用libjpeg库压缩和上一篇的解压正好对应起来,有好多函数名称我都是对称的起的,所以结合起来看效果更好。

  和上一篇一样,只能处理24位和8位的图像。

  代码如下:

#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;

struct bmp_fileheader bfh;
struct bmp_infoheader bih;

unsigned char *src_buffer;
unsigned char *dst_buffer;

void read_bmp_header()
{
fread(&bfh,sizeof(struct bmp_fileheader),1,input_file);
fread(&bih,sizeof(struct bmp_infoheader),1,input_file);
}

void read_bmp_data()
{
fseek(input_file,bfh.bfOffBits,SEEK_SET);
src_buffer=new unsigned char[bih.biWidth*bih.biHeight*bih.biBitCount/8];
fread(src_buffer,sizeof(unsigned char)*bih.biWidth*bih.biHeight*bih.biBitCount/8,1,input_file);

unsigned long width=bih.biWidth;
unsigned long height=bih.biHeight;
unsigned short depth=unsigned short(bih.biBitCount/8);
unsigned char *src_point;
unsigned char *dst_point;

dst_buffer=new unsigned char[width*height*depth];
src_point=src_buffer+width*depth*(height-1);
dst_point=dst_buffer+width*depth*(height-1);
for (unsigned long i=0;i<height;i++)
{
for (unsigned long j=0;j<width*depth;j+=depth)
{
if (depth==1)        //处理灰度图
{
dst_point[j]=src_point[j];
}

if (depth==3)        //处理彩色图
{
dst_point[j+2]=src_point[j+0];
dst_point[j+1]=src_point[j+1];
dst_point[j+0]=src_point[j+2];
}
}
dst_point-=width*depth;
src_point-=width*depth;
}
}

void synthese_jpeg()
{
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
JSAMPARRAY buffer;

unsigned long width=bih.biWidth;
unsigned long height=bih.biHeight;
unsigned short depth=unsigned short(bih.biBitCount/8);
unsigned char *point;

cinfo.err=jpeg_std_error(&jerr);        //libjpeg各种配置
jpeg_create_compress(&cinfo);
jpeg_stdio_dest(&cinfo,output_file);

cinfo.image_width=width;
cinfo.image_height=height;
cinfo.input_components=depth;
if (depth==1)
cinfo.in_color_space=JCS_GRAYSCALE;
else
cinfo.in_color_space=JCS_RGB;

jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo,20,TRUE);    //中间的值为压缩质量,越大质量越好
jpeg_start_compress(&cinfo,TRUE);

buffer=(*cinfo.mem->alloc_sarray)
((j_common_ptr)&cinfo,JPOOL_IMAGE,width*depth,1);

point=dst_buffer+width*depth*(height-1);
while (cinfo.next_scanline<height)
{
memcpy(*buffer,point,width*depth);
jpeg_write_scanlines(&cinfo,buffer,1);
point-=width*depth;
}

jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);
}

int main()
{
input_file=fopen("lena_gray.bmp","rb");
output_file=fopen("lena.jpg","wb");

read_bmp_header();
read_bmp_data();

synthese_jpeg();

fclose(input_file);
fclose(output_file);

delete[] src_buffer;
delete[] dst_buffer;

cout<<"good job."<<endl;
cin.get();
return 0;
}

注:其中重要的一点就是bmp格式的bgr要转换为rgb和y坐标系转换。

struct bmp_fileheader bfh;
struct bmp_infoheader bih;
unsigned char*pBuf = src + sizeof(struct bmp_fileheader) + sizeof(struct bmp_infoheader);
pBuf += width*(height-1)*3;
unsigned char* pDst = (unsigned char*)calloc(width*height*3,1);
unsigned char* pHead = pDst;
for (unsigned long i=0;i<height;i++)
{
for (unsigned long j=0;j<width*3;j+=3)
{
pHead[j+2]=pBuf[j+0];
pHead[j+1]=pBuf[j+1];
pHead[j+0]=pBuf[j+2];
}
pBuf -=width*3;
pHead += width*3;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  libjpeg rgb-to-jpg