• bmp转jpg(使用libjpeg)


      jpg压缩原理可以参考这篇文章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;
    }
  • 相关阅读:
    前端开发小结(持续更新)
    UDP 通讯及内部分析(合集)
    困扰我三天的问题
    Clang Format Style Options (.clang-format 配置文件文档)
    关于共享库的那些事儿
    如何在VMWare的NAT模式下使用traceroute(解析vmnat的行为)
    Linux网络配置
    Ansible Ad-Hoc命令集
    Ansible基础使用
    Ansible部署及配置介绍
  • 原文地址:https://www.cnblogs.com/tiandsp/p/2799561.html
Copyright © 2020-2023  润新知