zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    10. Regular Expression Matching
    9. Palindrome Number (考虑负数的情况)
    8. String to Integer (整数的溢出)
    7. Reverse Integer (整数的溢出)
    LeetCode Minimum Size Subarray Sum
    LeetCode Course Schedule II
    Linux 文件缓存 (一)
    LeetCode Tries Prefix Tree
    Linux : lsof 命令
    LeetCode Binary Tree Right Side View
  • 原文地址:https://www.cnblogs.com/tiandsp/p/2799561.html
Copyright © 2011-2022 走看看