zoukankan      html  css  js  c++  java
  • 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()有内存泄露,不想在源代码上编辑了。

      

  • 相关阅读:
    vue学习
    BBS登录注册技术点归纳
    BBS项目模态框的使用
    django后台管理系统
    java 之 jsp简介
    http 之 CORS简介
    web 之 session
    linux 之学习路线
    Ubuntu 之 win10更新ubuntu启动项消失
    Web 之 Cookie
  • 原文地址:https://www.cnblogs.com/tiandsp/p/2796758.html
Copyright © 2011-2022 走看看