zoukankan      html  css  js  c++  java
  • 利用jpeglib压缩各种图像格式为jpg格式,linux下bmp转化为jpeg程序源代码

     

      本文只介绍jpeg压缩的相关内容,刚开始我贪图省事,采用微软 的GDI Plus提供的功能,很是方便,先获取jpg图像的编码,然后根据图像的位图数据创建一个Bitmap类的对象,再保存图像为jpg格式就行了。但是我对 GDI+还是很信任,总感觉不踏实(没有理由的),我们的系统一旦安装就要长期运行,我就是担心长期运行一段时间后GDI+会出问题,结果也证实了我的担 心,我们实际使用的10套系统中有一套,连续运行3-5天后,GDI+就会崩溃,于是我决心采用IJG JPEG Library。您可以到www.ijg.org网 站下载libjpeg的源码, IJG JPEG Library就是jpeg压缩库,是以源码的形式提供给软件开发人员的,当然在软件包里也有编译好的库文件,我们这里就只用到其中的 libjpeg.lib(名字也可能是libjpeg.la),jconfig.h,jmorecfg.h,jpeglib.h这几个文件,下面我就介绍一下怎样在自己的程序里嵌入图像压缩功 能。

      一、建立编译环境

      所谓建立编译环境,其实非常简单,就是把上面提到的4个文件拷贝到你的项目文件夹下,把libjpeg.lib添加到你的项目中,然后在你完成 压缩功能的那个文件里加入#include "jpeglib.h",需要注意的是,libjpeg.lib是用c语言开发的,如果要用在你的C++程序里,需要用到extern "C",如下:

    // TestLibjpeg.cpp : Defines the entry point for the console application.
    //

    #include "stdafx.h"
    #include "memory.h"
    extern "C" {
    #include "jpeglib.h"
    }

      二、压缩步骤

      1、申请并初始化jpeg压缩对象,同时要指定错误处理器

    struct jpeg_compress_struct jcs;

    // 声明错误处理器,并赋值给jcs.err域
    struct jpeg_error_mgr jem;
    jcs.err = jpeg_std_error(&jem);

    jpeg_create_compress(&jcs);

      2、指定压缩后的图像所存放的目标文件,注意,目标文件应以二进制模式打开

    f=fopen("03.jpg","wb");
    if (f==NULL) 
    {
    delete [] data;
    delete [] pDataConv;
    return 0;
    }
    jpeg_stdio_dest(&jcs, f);

      3、设置压缩参数,主要参数有图像宽、高、色彩通道数(1:索引图像,3:其他),色彩空间(JCS_GRAYSCALE表示灰度图,JCS_RGB表示彩色图像),压缩质量等,如下:

    jcs.image_width = nWidth;    // 为图的宽和高,单位为像素 
    jcs.image_height = nHeight;
    jcs.input_components = 1;   // 在此为1,表示灰度图, 如果是彩色位图,则为3 
    jcs.in_color_space = JCS_GRAYSCALE; //JCS_GRAYSCALE表示灰度图,JCS_RGB表示彩色图像

       jpeg_set_defaults(&jcs); 
    jpeg_set_quality (&jcs, 80, true);

    需要注意的是,jpeg_set_defaults函数一定要等设置好图像宽、高、色彩通道数计色彩空间四个参数后才能调用,因为这个函数要用到这 四个值,调用jpeg_set_defaults函数后,jpeglib库采用默认的设置对图像进行压缩,如果需要改变设置,如压缩质量,调用这个函数 后,可以调用其它设置函数,如jpeg_set_quality函数。其实图像压缩时有好多参数可以设置,但大部分我们都用不着设置,只需调用 jpeg_set_defaults函数值为默认值即可。

      4、上面的工作准备完成后,就可以压缩了,压缩过程非常简单,首先调用jpeg_start_compress,然后可以对每一行进行压缩,也 可以对若干行进行压缩,甚至可以对整个的图像进行一次压缩,压缩完成后,记得要调用jpeg_finish_compress函数,如下:

    jpeg_start_compress(&jcs, TRUE);

    JSAMPROW row_pointer[1];   // 一行位图
    int row_stride;      // 每一行的字节数

    row_stride = jcs.image_width; // 如果不是索引图,此处需要乘以3(每位像素所占的字节数)

       // 对每一行进行压缩
    while (jcs.next_scanline < jcs.image_height) {
    row_pointer[0] = & pDataConv[jcs.next_scanline * row_stride];
    jpeg_write_scanlines(&jcs, row_pointer, 1);
    }

     jpeg_finish_compress(&jcs);

      5、最后就是释放压缩工作过程中所申请的资源了,主要就是jpeg压缩对象,由于在本例中我是直接用的局部变量,所以只需调用jpeg_destroy_compress这个函数即可,如下:

    jpeg_destroy_compress(&jcs);

      三、解压缩步骤
    解压缩步骤与压缩步骤非常相似,只是解压缩对象为jpeg_decompress_struct类型,步骤如下:
    1、声明并初始化解压缩对象,同时制定错误信息管理器
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;

    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_decompress(&cinfo);
    2、打开jpg图像文件,并指定为解压缩对象的源文件
    FILE *f = fopen(strSourceFileName,"rb");
    if (f==NULL)
    {
    printf("Open file error!\n");
    return;
    }
    // 
    jpeg_stdio_src(&cinfo, f);
    3、读取图像信息
    jpeg_read_header(&cinfo, TRUE);
    4、根据图像信息申请一个图像缓冲区
    data = new BYTE cinfo.image_width*cinfo.image_height*cinfo.num_components];
    5、开始解压缩
    jpeg_start_decompress(&cinfo);

    JSAMPROW row_pointer[1];
    while (cinfo.output_scanline < cinfo.output_height)
    {
    row_pointer[0] = &data[(cinfo.output_height - cinfo.output_scanline-1)*cinfo.image_width*cinfo.num_components];
    jpeg_read_scanlines(&cinfo,row_pointer ,
    1);
    }
    jpeg_finish_decompress(&cinfo);
    6、释放资源
    jpeg_destroy_decompress(&cinfo);

    fclose(f);

      好了,利用IJG JPEG Library进行图像压缩就介绍到这里,希望对大家有所帮助,实例代码已经实现了图像的压缩和解压缩的全部功能,命令格式 为:“TestLibjpeg.exe j|j24|b 源文件名 目标文件名”,其中,j选项将源文件压缩为jpg格式,不改变色彩模式,j24选项将源文件压缩为24为jpg格式,b选项将源文件解压缩为bmp格式, 该实例并没有提供文件有效性的验证,如果要引入自己的代码,请自己实现文件有效性的验证。 

    linux下bmp转化为jpeg程序源代码

     
    
    /****************************************************************************
    
    名称:   bmp-to-jpeg.c
    功能:   linux下bmp转化为jpeg程序源代码
    版权:   西南交通大学,信号与信息处理四川省重点实验室
    作者:   黄文辉
    日期:   2010.01.26
    注意:   编译时加“-ljpeg”(gcc -o mm bmp-to-jpeg.c -ljpeg)
    
    *****************************************************************************/
    
    #include <string.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <sys/ioctl.h>
    #include <sys/mman.h>
    #include <linux/videodev.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <errno.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <sys/timeb.h>
    #include <jpeglib.h>
    
    #define JPEG_QUALITY 80
    
    
    int main()
    {
    FILE *fd;
    int ret;
    unsigned char *data;
    long sizeImage;
    sizeImage = 320*240*sizeof(unsigned char);
    data = (unsigned char*)malloc(sizeImage);
    fd = fopen("palm.bmp", "rb");
    if(!fd)
    {
    printf("ERROR1: Can not open the image.\n");
    free(data);
    return -1;
    }
    
    //    跳过bmp文件头,直接读取掌纹图像数据
    fseek(fd, 1078, SEEK_SET);   
    ret = fread(data, sizeof(unsigned char)*sizeImage, 1, fd);
    if(ret == 0)
    {
    if(ferror(fd))
    {
    printf("\nERROR2: Can not read the pixel data.\n");
    free(data);
    fclose(fd);
    return -1;
    }
    }
    
    
    char *filename = "palm2.jpg";
    int width = 320;
    int height = 240;
    int depth = 1;
    //unsigned char *bits = "jsdgjksdjkgjks51sd536gsgjmskjgksjgss231h1b2s123z";
    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;
    FILE *outfile;                 /* target file */
    JSAMPROW row_pointer[1];        /* pointer to JSAMPLE row[s] */
    int     row_stride;             /* physical row width in image buffer */
    
    cinfo.err = jpeg_std_error(&jerr);
    /* Now we can initialize the JPEG compression object. */
    jpeg_create_compress(&cinfo);
    
    if ((outfile = fopen(filename, "wb")) == NULL) {
    fprintf(stderr, "can't open %s\n", filename);
    return -1;
    }
    jpeg_stdio_dest(&cinfo, outfile);
    
    cinfo.image_width = width;      /* image width and height, in pixels */
    cinfo.image_height = height;
    cinfo.input_components = depth;         /* # of color components per pixel */
    cinfo.in_color_space = JCS_GRAYSCALE;         /* colorspace of input image */
    
    jpeg_set_defaults(&cinfo);
    /* Now you can set any non-default parameters you wish to.
    * Here we just illustrate the use of quality (quantization table) scaling:
    */
    jpeg_set_quality(&cinfo, JPEG_QUALITY, TRUE ); /* limit to baseline-JPEG values */
    
    jpeg_start_compress(&cinfo, TRUE);
    
    row_stride = width; /* JSAMPLEs per row in image_buffer */
    
    while (cinfo.next_scanline < cinfo.image_height) {
    row_pointer[0] = & data[cinfo.next_scanline * row_stride];
    (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
    }
    
    jpeg_finish_compress(&cinfo);
    jpeg_destroy_compress(&cinfo);
    
    free(data);   
    fclose(fd);
    fclose(outfile);
    
    return 0;
    }

      原文链接:http://blog.chinaunix.net/uid-26544753-id-3049279.html

  • 相关阅读:
    VMware workstation安装linux(ubuntu)配置详解
    虚拟机的三种网络模式
    虚拟机(VMware Workstation)的使用方法
    零基础学习hadoop到上手工作线路指导(初级篇)
    Hadoop到底能做什么?怎么用hadoop?
    什么是云计算技术
    什么是云计算
    静态数据库迁移
    apache-mysql-php安装与配置
    CentOS6.6下的authpuppy源码安装与配置完全纯净版,内有问题解答
  • 原文地址:https://www.cnblogs.com/beanmoon/p/2748660.html
Copyright © 2011-2022 走看看