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()有内存泄露,不想在源代码上编辑了。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
用于将jpeg文件换成为bmp文件, MICROSOFT FOUNDATION CLASS LIBRARY : JpgVSbmp ======================================================================== AppWizard has created this JpgVSbmp DLL for you. This DLL not only demonstrates the basics of using the Microsoft Foundation classes but is also a starting point for writing your DLL. This file contains a summary of what you will find in each of the files that make up your JpgVSbmp DLL. JpgVSbmp.dsp This file (the project file) contains information at the project level and is used to build a single project or subproject. Other users can share the project (.dsp) file, but they should export the makefiles locally. JpgVSbmp.h This is the main header file for the DLL. It declares the CJpgVSbmpApp class. JpgVSbmp.cpp This is the main DLL source file. It contains the class CJpgVSbmpApp. JpgVSbmp.rc This is a listing of all of the Microsoft Windows resources that the program uses. It includes the icons, bitmaps, and cursors that are stored in the RES subdirectory. This file can be directly edited in Microsoft Visual C++. JpgVSbmp.clw This file contains information used by ClassWizard to edit existing classes or add new classes. ClassWizard also uses this file to store information needed to create and edit message maps and dialog data maps and to create prototype member functions. res\JpgVSbmp.rc2 This file contains resources that are not edited by Microsoft Visual C++. You should place all resources not editable by the resource editor in this file. JpgVSbmp.def This file contains information about the DLL that must be provided to run with Microsoft Windows. It defines parameters such as the name and description of the DLL. It also exports functions from the DLL. ///////////////////////////////////////////////////////////////////////////// Other standard files: StdAfx.h, StdAfx.cpp These files are used to build a precompiled header (PCH) file named JpgVSbmp.pch and a precompiled types file named StdAfx.obj. Resource.h This is the standard header file, which defines new resource IDs. Microsoft Visual C++ reads and updates this file. ///////////////////////////////////////////////////////////////////////////// Other notes: AppWizard uses "TODO:" to indicate parts of the source code you should add to or customize.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值