jpg转bmp(使用libjpeg)

原文链接:http://www.cnblogs.com/tiandsp/archive/2012/11/30/2796758.html


  还是关于图像格式上的东西。使用了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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
介绍如何在linux下编译生成libjpeg库,然后调用libjpeg库将BMP图片JPG图片。 tar jvxf libtool-2.2.4.tar.bz2 cd libtool-2.2.4/ ./configure CC=arm-linux-gnu-gcc --build=i686-linux --host=arm-linux --prefix=$PWD/_install ./configure CC=gcc --build=i686-linux --prefix=$PWD/_install ./configure CC=gcc --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu --prefix=$PWD/_install ./configure CC=arm-linux-gcc --build=i686-linux-gnu --host=arm-linux --target=arm-linux --prefix=$PWD/_install make && make install tar zvxf jpegsrc.v6b.tar.gz cd jpeg-6b ./configure CC=arm-linux-gnu-gcc --prefix=$PWD/_install --enable-shared --enable-static --host=arm-linux ./configure CC=gcc --prefix=$PWD/_install --enable-shared --enable-static ./configure CC=gcc --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu --prefix=$PWD/_install --enable-shared --enable-static ./configure CC=arm-linux-gcc --build=i686-linux-gnu --host=arm-linux --target=arm-linux --prefix=$PWD/_install --enable-shared --enable-static mkdir -p _install/bin _install/include _install/lib _install/man/man1 make && make install root@ubuntu:/home/disk2/PP1938-V2.4.1/bmp2jpg# arm-linux-gcc -v Using built-in specs. Target: arm-linux Configured with: ../gcc-4.3.2/configure --target=arm-linux --prefix=/home/magus/toolchain/cross-tools --enable-languages=c,c++ --enable-threads=posix --enable-shared --enable-__cxa_atexit --with-arch=armv6 --with-cpu=arm1176jzf-s --with-tune=arm1176jzf-s --with-fpu=vfp --with-float=softfp --enable-c99 --enable-long-long --disable-nls --with-sysroot=/home/magus/toolchain Thread model: posix gcc version 4.3.2 (GCC) root@ubuntu:/home/disk2/PP1938-V2.4.1/bmp2jpg# gcc -v Using built-in specs. Target: i686-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.4.4-14ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.4 --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu Thread model: posix gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5) root@ubuntu:/home/disk2/PP1938-V2.4.1/bmp2jpg#

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值