转【PNG overview】PNG专题

PNG定义了两种类型的数据块,一种是称为关键数据块(critical chunk),这是标准的数据块,另一种叫做辅助数据块(ancillary chunks),这是可选的数据块。关键数据块定义了4个标准数据块,每个PNG文件都必须包含它们,PNG读写软件也都必须要支持这些数据块。虽然PNG文件规范没有要求PNG编译码器对可选数据块进行编码和译码,但规范提倡支持可选数据块。

下表就是PNG中数据块的类别,其中,关键数据块部分我们使用深色背景加以区分。

PNG文件格式中的数据块
           
数据块符号
           
数据块名称
多数据块
可选否
位置限制
IHDR 文件头数据块 第一块
cHRM 基色和白色点数据块 在PLTE和IDAT之前
gAMA 图像γ数据块 在PLTE和IDAT之前
sBIT 样本有效位数据块 在PLTE和IDAT之前
PLTE 调色板数据块 在IDAT之前
bKGD 背景颜色数据块 在PLTE之后IDAT之前
hIST 图像直方图数据块 在PLTE之后IDAT之前
tRNS 图像透明数据块 在PLTE之后IDAT之前
oFFs (专用公共数据块) 在IDAT之前
pHYs 物理像素尺寸数据块 在IDAT之前
sCAL (专用公共数据块) 在IDAT之前
IDAT 图像数据块 与其他IDAT连续
tIME 图像最后修改时间数据块 无限制
tEXt 文本信息数据块 无限制
zTXt 压缩文本数据块 无限制
fRAc (专用公共数据块) 无限制
gIFg (专用公共数据块) 无限制
gIFt (专用公共数据块) 无限制
gIFx (专用公共数据块) 无限制
IEND 图像结束数据 最后一个数据块

为了简单起见,我们假设在我们使用的PNG文件中,这4个数据块按以上先后顺序进行存储,并且都只出现一次。

数据块结构
 

PNG文件中,每个数据块由4个部分组成,如下:

名称 字节数 说明
Length (长度) 4字节 指定数据块中数据域的长度,其长度不超过(231-1)字节
Chunk Type Code (数据块类型码) 4字节 数据块类型码由ASCII字母(A-Z和a-z)组成
Chunk Data (数据块数据) 可变长度 存储按照Chunk Type Code指定的数据
CRC (循环冗余检测) 4字节 存储用来检测是否有错误的循环冗余码

CRC(cyclic redundancy check)域中的值是对Chunk Type Code域和Chunk Data域中的数据进行计算得到的。CRC具体算法定义在ISO 3309和ITU-T V.42中,其值按下面的CRC码生成多项式进行计算:

x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1

下面,我们依次来了解一下各个关键数据块的结构吧。

2.PNG格式四大金刚

PNG必需的关键数据块主要是有四分组成,分别是IHDR,PLTE,IDAT,IEND ,其中PLTE 数据块只是和索引彩色图像有关的,如果是RGB格式的PNG,里面可以没有PLTE数据。这样来说其实PNG数据的主要分就是三部分IHDR,IDAT,IEND-----分别是文件头,数据部分和文件结尾。

IHDR
 

文件头数据块IHDR(header chunk):它包含有PNG文件中存储的图像数据的基本信息,并要作为第一个数据块出现在PNG数据流中,而且一个PNG数据流中只能有一个文件头数据块。

文件头数据块由13字节组成,它的格式如下表所示。

域的名称
字节数
说明
Width 4 bytes 图像宽度,以像素为单位
Height 4 bytes 图像高度,以像素为单位
Bit depth 1 byte 图像深度:
索引彩色图像:1,2,4或8
灰度图像:1,2,4,8或16
真彩色图像:8或16
ColorType 1 byte 颜色类型:
0:灰度图像, 1,2,4,8或16
2:真彩色图像,8或16
3:索引彩色图像,1,2,4或8
4:带α通道数据的灰度图像,8或16
6:带α通道数据的真彩色图像,8或16
Compression method 1 byte 压缩方法(LZ77派生算法)
Filter method 1 byte 滤波器方法
Interlace method 1 byte 隔行扫描方法:
0:非隔行扫描
1: Adam7(由Adam M. Costello开发的7遍隔行扫描方法)

现在用图片点击可在新窗口打开查看UltraEdit-32打开上面的那张PNG格式测试图,我们开始分析它的数据结构。


图片点击可在新窗口打开查看[快车下载]
图片点击可在新窗口打开查看

被红色选中的头8个字节即为PNG文件的标识,它说名了这个文件是一个PNG文件。
除了被红色选中的以外的白色部分,就是IHDR自身描述的数据块了

  • 00 00 00 0D 说明IHDR头块长为13
  • 49 48 44 52 IHDR标识
  • 00 00 01 00 图像的宽,256像素
  • 00 00 01 00 图像的高,256像素
  • 08 色深
  • 02 颜色类型,真彩色图像
  • 00 PNG Spec规定此处总为0(非0值为将来使用更好的压缩方法预留),表示使压缩方法(LZ77派生算法)
  • 00 同上
  • 00 非隔行扫描
  • 最后的4位数据是 CRC校验码  确保以上数据的完整性

    PLTE
     

    调色板数据块PLTE(palette chunk)包含有与索引彩色图像(indexed-color image)相关的彩色变换数据,它仅与索引彩色图像有关,而且要放在图像数据块(image data chunk)之前。

    PLTE数据块是定义图像的调色板信息,PLTE可以包含1~256个调色板信息,每一个调色板信息由3个字节组成:

    颜色
          

    字节
          

    意义
          

    Red

    1 byte

    0 = 黑色, 255 = 红

    Green

    1 byte

    0 = 黑色, 255 = 绿色

    Blue

    1 byte

    0 = 黑色, 255 = 蓝色

    因此,调色板的长度应该是3的倍数,否则,这将是一个非法的调色板。

    对于索引图像,调色板信息是必须的,调色板的颜色索引从0开始编号,然后是1、2……,调色板的颜色数不能超过色深中规定的颜色数(如图像色深为4的时候,调色板中的颜色数不可以超过2^4=16),否则,这将导致PNG图像不合法。

    • 真彩色图像和带α通道数据的真彩色图像也可以有调色板数据块,目的是便于非真彩色显示程序用它来量化图像数据,从而显示该图像。

      因为这张测试图片是真彩图像,所以没有PLTE数据块。

      IDAT
       

      图像数据块IDAT(image data chunk):它存储实际的数据,在数据流中可包含多个连续顺序的图像数据块。

      IDAT存放着图像真正的数据信息,因此,如果能够了解IDAT的结构,我们就可以很方便的生成PNG图像。 


      图片点击可在新窗口打开查看[快车下载]
      图片点击可在新窗口打开查看
      在这留白的部分就是我们的IDAT数据部分

    • 红色选中部分表示IDAT数据块的长度
    • 黄色部分49 44 41 54 IDAT标识
    • 78 DA…… 压缩的数据,LZ77派生压缩方法
    • 绿色部分是 CRC校验
       

      IEND
       

      图像结束数据IEND(image trailer chunk):它用来标记PNG文件或者数据流已经结束,并且必须要放在文件的尾部。

      如果我们仔细观察PNG文件,我们会发现,文件的结尾12个字符看起来总应该是这样的:

      00 00 00 00 49 45 4E 44 AE 42 60 82

      不难明白,由于数据块结构的定义,IEND数据块的长度总是0(00 00 00 00,除非人为加入信息),数据标识总是IEND(49 45 4E 44),因此,CRC码也总是AE 42 60 82。

    至此,我们已经能够从一个PNG文件中识别出各个数据块了。由于PNG中规定除关键数据块外,其它的辅助数据块都为可选部分,因此,有了这个标准后,我们可以通过删除所有的辅助数据块来减少PNG文件的大小。(当然,需要注意的是,PNG格式可以保存图像中的层、文字等信息,一旦删除了这些辅助数据块后,图像将失去原来的可编辑性。)

    比如说下面这个图形数据,里面除了我们上面所提到的四块数据以外,还有很多的辅助数据

    图片点击可在新窗口打开查看

    3.PNG格式的天兵天将

    我们选择网上的一张图片作为讲解PNG辅助格式的图片素材图片点击可在新窗口打开查看,这个素材是8*8的,看起来很小,放大以后效果如下图,不过查看数据格式的时候还是要用图片点击可在新窗口打开查看UltraEdit-32打开图片点击可在新窗口打开查看
    图片点击可在新窗口打开查看

    主要的数据块我们就不讲了,现在看看辅助数据

    00000021~0000002F:
     

    图片点击可在新窗口打开查看
     

    可选数据块sBIT,颜色采样率,RGB都是256(2^8=256)

    00000030~00000062:
     

    图片点击可在新窗口打开查看
     

    这里是调色板信息

    • 00 00 00 27 说明调色板数据长为39字节,既13个颜色数
    • 50 4C 54 45 PLTE标识 (开始那张图片上面没有PLTE数据块,这张图片有)
    • FF FF 00 颜色0
    • FF ED 00 颜色1
    • …… ……
    • 09 00 B2 最后一个颜色,12
    • 5F F5 BB DD CRC校验

    00000063~000000C5:

     

    图片点击可在新窗口打开查看
     

    这部分包含了pHYs、tExt两种类型的数据块共3块,由于并不太重要,因此也不再详细描述了。

    4.PNG格式测试

    图片点击可在新窗口打开查看
    For the 21st century

    PNG Image Format

     

    Portable Network Graphics - PNG

    图片点击可在新窗口打开查看

    PNG 的压缩算法应该说是相当优秀的.他并不像JPEG images, PNG 采用的是无损压缩, 这样我们看到的图像就不会存在像素损失,也不会模糊. In some cases, filtering can compress the image data even more. Each horizontal line in an image can have one of five filter types associated with it. Whether specifying a filter helps in a particular case depends on the image content. In most cases the default setting is best ( adaptive filtering ).

    作为 PNG Development Group(PNG发展组)的一员, Paul Schmidt, 生成了一个 test image 包含pixels of all 16.7 million possible colors. 他是841:1的压缩比. 是一个非常棒的 24 bit PNG 图像.
    View a screenshot and more examples.

    PNG color depth

    真彩 24 bit images are one of fifteen color optionsin PNG format. Images can be created using color palettes(调色板) or 8 bit grayscale(灰阶). Pixel data with 8 bit values can index into palettes containing(包含) up to 256 colors, and with fewer colors pixel values can be 1, 2 or 4 bits. For specialist requirements PNG also offers 48 bit true color and 16 bit grayscale.

    PNG transparency(透明)

    PNG 2位透明格式试图取代 GIF透明 图像.这一点也是相当令人激动的 -- 可变透明, 这就是我们常常提到的"alpha transparency", "alpha-channel transparency"(alpha 透明;alpha 通道), or 简单的称之为 "mask channel". 它允许你在全透明不透明之间有254个阶可以选择.

    最近公布的PNG's 可变透明, 包含 WebTV and Microsoft Internet Explorer for Macs. 但是Pre-IE7versions of Internet Explorer 例外, 但是背景透明还是有的.  IE6 for Windows支持 PNG's 单色透明. The image below shows some examples:

    1. 24 bit PNG with alpha transparency.
    2. 8 bit PNG with binary transparency.
    3. First example in pre-IE7 versions of Internet Explorer for Windows.
    4. 8 bit GIF with binary transparency.
    图片点击可在新窗口打开查看

    PNG interlaced images(交错图像)

    Interlaced GIF images display their data in 4 passes, each one filling in more detail from top to bottom. The first pass begins after 1/8 of the image has downloaded. PNG uses a more sophisticated scheme which begins rendering the image after only 1/64 of the data has arrived. PNG's 7 pass scheme, devised by Adam Costello, fills in increasing amounts of detail both horizontally and vertically. Interlacing increases the file size. You may find that with PNG's better compression fewer images will need interlacing. For exceptionally large image files thumbnail preview images are another option.

    Extra features

    PNG format allows all kinds of extra information to be stored inside image files. The two most potentially helpful features for web images are gamma correction and embedded text.

    Gamma correction is the ability to correct for differences in how computer systems interpret color values. Macintosh-generated images tend to look too dark on PCs, and PC-generated images tend to look too light on Macs. PNG format allows the gamma value of the computer which created an image to be embedded into the image file. Browsers and image software which support the feature can extract the gamma value and make a correction if the host computer uses a different gamma setting. Warning: There are some applications which don't implement it correctly. Don't rely on gamma correction to match image colors to HTML/CSS colors.

    The text feature makes it possible to add any text annotations you like -- a description of the image, the date of creation, copyright information, etc. Very few image editors offer this option, but the TweakPNG utility allows you to add text after the image has been created. It can also set the background color of a PNG alpha image. The default background color is gray inpre-IE7 versions of Internet Explorer for Windows.

    PNG - the background story

    In the late 1980's CompuServe introduced a new image format which became popular with internet users - Graphic Interchange Format, or GIF. It used a long-established compression algorithm, LZW, without realizing that LZW was subject to a patent filed by the Sperry corporation, which was later taken over by Unisys.

    In late 1994 Unisys dropped a bombshell by announcing that the company would start demanding royalties from all developers of GIF-supporting software. The announcement caused consternation among the internet community and ideas were passed around for a non-proprietary replacement. An informal internet working group was established by Thomas Boutell to devise an image format which would be even better than GIF. In October 1996, the World Wide Web Consortium adopted the new specification, Portable Network Graphics, as a recommended image format.

    By late 1997 both Netscape 4 and Internet Explorer 4 had arrived with basic support for PNG images. Support for the more advanced features followed. Now, binary transparency andinterlacing are supported by all modern browsers, but pre-IE7 versions of Internet Explorer for Windows don't directly support PNG's most advanced feature, alpha-transparency. However, remedies are available using PHP or JavaScript:
    Internet Explorer and PNG transparency.

    图片点击可在新窗口打开查看

    The LZW patent in the United States expired in June 2003, and up to a year later in other countries. More information about patent controversies can be found at:

    A comprehensive source of information about Portable Network Graphics format is maintained by one of the original members of the PNG working group, Greg Roelofs:

    He is also the author of "PNG: The Definitive Guide". An online version is available at the site. Greg kindly provided examples of minimum-size PNG files to compare with the output of image converters reviewed on this site:
    Review of PNG image tools for MS Windows.

    图片点击可在新窗口打开查看

    By late 2003 the number of internet users with browsers dating back to 1997 or earlier was negligible. They would see image placeholders instead of the images.

    Animation

    Portable Network Graphics format was originally devised at a time when there was no browser support for GIF animation, so animation was not included in the specification. Later, a separate animation format was devised with a whole host of advanced features - Multiple-image Network Graphics, or MNG. As it turned out, however, the arrival of other animation technologies such as Macromedia Flash took attention away from MNG format. More information about MNG can be found at the PNG Home Site.

    The lack of sophistication in GIF animation can be annoying to users. Research into user reactions has shown that some users cover animations with one hand as they read the text on a page.Here's a tip: GIF animations can be frozen by pressing the ESC key in Internet Explorer or Firefox.

    Choosing an image format

    • For photos and scans JPEG will almost always be more compact than 24 bit PNG format.
    • For true color images containing text and sharp color transitions 24 bit PNG could turn out smaller, and will certainly provide the best quality. Ideal for maps, charts and diagrams with more than 256 colors.
    • If the quality is acceptable, converting true color images to a 8 bit palette can often produce a smaller file. Dither the colors if necessary.
    • For converting GIF images, use 8 bit PNG. With the right image tools only tiny GIF files remain smaller than a PNG equivalent (small icons, for example).
    • Use single-color transparency if alpha-channel transparency is not really necessary. It works in Internet Explorer and the file size will most likely be smaller.
    • There's a small overhead for PNG's versatility: the minimum file size is 67 bytes for an opaque single pixel.

    The official PNG specification

    A complete list of features can be found in the official PNG specification at the World Wide Web Consortium's website:

    第三章  PNG格式的读写
        1.PNG格式C语言读写

          PNG格式读写离不开PNG库libpng 是一套免费的、公开源代码的程序库,支持对 PNG 图形文件的创建、读写等操作。可以到www.libpng.org 上下载源代码。libpng 使用 zlib 程序库作为压缩引擎,zlib 也是著名的 gzip (GNU zip) 所采用的压缩引擎。zlib 是通用的压缩库,提供了一套 in-memory 压缩和解压函数,并能检测解压出来的数据的完整性(integrity)。zlib 也支持读写 gzip (.gz) 格式的文件这些都是免费和公开的。在下载了pbglib,并且要下载zlib,如何才能加到代码中呢?以VC6.为例来说明。其他CBuild等编译器相信也一样的。

           比如我们从网上下载了一个lpng1210.zip和zlib-.2.3.tar.tar。首先把他们解压。在lpng的目录中寻找projects/visualc6/libpng.dsw。并在zlib中寻找zlib-1.2.3/projects/visualc6/zlib.dsw。用vc打开libpng工程文件,把zlib的工程文件也添加进去。设置好在setting中设置好的zlib.lib和pbg.lib的输出路径,以及include路径(这个简单方法相信大家都明白吧)。运行后,就生成了两个静态库了。

          lib做好以后,就可以将lib加到我们要做的工程中去。在link中设置好,并将png.h和zlib.h都加进去。这样就可以正式的使用libpng了!如果还有不明白的地方,在这里留言或者在百度上搜一下。

    下面将将到重点内容了。如何用pnglib实现对文件的读写?A simple libpng example program(http://zarb.org/~gc/html/libpng.html

    以下就是写好的PNG读取和写入函数

    #include <unistd.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdarg.h>

    #define PNG_DEBUG 3
    #include <png.h>

    void abort_(const char * s, ...)
    {
     va_list args;
     va_start(args, s);
     vfprintf(stderr, s, args);
     fprintf(stderr, "/n");
     va_end(args);
     abort();
    }

    int x, y;

    int width, height;
    png_byte color_type;
    png_byte bit_depth;

    png_structp png_ptr;
    png_infop info_ptr;
    int number_of_passes;
    png_bytep * row_pointers;

    void read_png_file(char* file_name)
    {
     char header[8]; // 8 is the maximum size that can be checked

     
     FILE *fp = fopen(file_name, "rb");
     if (!fp)
      abort_("[read_png_file] File %s could not be opened for reading", file_name);
     fread(header, 1, 8, fp);
     if (png_sig_cmp(header, 0, 8))
      abort_("[read_png_file] File %s is not recognized as a PNG file", file_name);


     
     png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
     
     if (!png_ptr)
      abort_("[read_png_file] png_create_read_struct failed");

     info_ptr = png_create_info_struct(png_ptr);
     if (!info_ptr)
      abort_("[read_png_file] png_create_info_struct failed");

     if (setjmp(png_jmpbuf(png_ptr)))
      abort_("[read_png_file] Error during init_io");

     png_init_io(png_ptr, fp);
     png_set_sig_bytes(png_ptr, 8);

     png_read_info(png_ptr, info_ptr);

     width = info_ptr->width;
     height = info_ptr->height;
     color_type = info_ptr->color_type;
     bit_depth = info_ptr->bit_depth;

     number_of_passes = png_set_interlace_handling(png_ptr);
     png_read_update_info(png_ptr, info_ptr);


     
     if (setjmp(png_jmpbuf(png_ptr)))
      abort_("[read_png_file] Error during read_image");

     row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height);
     for (y=0; y<height; y++)
      row_pointers[y] = (png_byte*) malloc(info_ptr->rowbytes);

     png_read_image(png_ptr, row_pointers);

            fclose(fp);
    }

    写入PNG格式

    void write_png_file(char* file_name)
    {
     
     FILE *fp = fopen(file_name, "wb");
     if (!fp)
      abort_("[write_png_file] File %s could not be opened for writing", file_name);


     
     png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
     
     if (!png_ptr)
      abort_("[write_png_file] png_create_write_struct failed");

     info_ptr = png_create_info_struct(png_ptr);
     if (!info_ptr)
      abort_("[write_png_file] png_create_info_struct failed");

     if (setjmp(png_jmpbuf(png_ptr)))
      abort_("[write_png_file] Error during init_io");

     png_init_io(png_ptr, fp);


     
     if (setjmp(png_jmpbuf(png_ptr)))
      abort_("[write_png_file] Error during writing header");

     png_set_IHDR(png_ptr, info_ptr, width, height,
           bit_depth, color_type, PNG_INTERLACE_NONE,
           PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);

     png_write_info(png_ptr, info_ptr);


     
     if (setjmp(png_jmpbuf(png_ptr)))
      abort_("[write_png_file] Error during writing bytes");

     png_write_image(png_ptr, row_pointers);


     
     if (setjmp(png_jmpbuf(png_ptr)))
      abort_("[write_png_file] Error during end of write");

     png_write_end(png_ptr, NULL);

           
     for (y=0; y<height; y++)
      free(row_pointers[y]);
     free(row_pointers);

            fclose(fp);
    }


    void process_file(void)
    {
     if (info_ptr->color_type != PNG_COLOR_TYPE_RGBA)
      abort_("[process_file] color_type of input file must be PNG_COLOR_TYPE_RGBA (is %d)", info_ptr->color_type);

     for (y=0; y<height; y++) {
      png_byte* row = row_pointers[y];
      for (x=0; x<width; x++) {
       png_byte* ptr = &(row[x*4]);
       printf("Pixel at position [ %d - %d ] has the following RGBA values: %d - %d - %d - %d/n",
              x, y, ptr[0], ptr[1], ptr[2], ptr[3]);

       
       ptr[0] = 0;
       ptr[1] = ptr[2];
      }
     }

    }


    int main(int argc, char **argv)
    {
     if (argc != 3)
      abort_("Usage: program_name <file_in> <file_out>");

     read_png_file(argv[1]);
     process_file();
     write_png_file(argv[2]);

            return 0;
    }

     

              在读取PNG的时候要注意读取顺序和调色板等设置,这在你读取数据以后对它进行操作(修改,保存)都很重要,否则会出现花屏或者写入的文件无法正常读取的问题。

    2.MFC中Cimage类读,写,显示PNG

          PNG格式的图片在MFC中的读写要比C语言容易很多,既有现成的插件和库,也有很多的代码工程可以使用,但是如果自己需要写一个自己的处理FMC还是有一定难度的,可以说,如果要自己控制PNG的读写,上面C语言的读写PNG方法不可缺少。有的人可能就问了,为什么别人都写好的东西,我们还要去写自己的PNG读写程序呢?反复造车轮的设计可不是现在的设计思想。既然已经说到这里饿,那么我们就来看看现在主要的PNG处理库吧。

    3.MFC中CxImage读,写,显示PNG

    一。CxImage类库简介

    这只是翻译了CxImage开源项目主页上的部分简介及简单使用。

    CxImage类库是一个优秀的图像操作类库。它可以快捷地存取、显示、转换各种图像。有的读者可能说,有那么多优秀的图形库,如OpenIL,FreeImage,PaintLib等等,它们可谓是功能强大,齐全,没必要用其它的类库。但我要说,这些类库基本上没有免费的,使用这些类库,你要被这样那样的许可协议所束缚。在这点上,CxImage类库是完全免费的。另外,在使用上述类库时,你会遇到重重麻烦。因为它们大部分是平台无关的,且用C语言写成,有的还夹杂着基本的C++ wrapper和成堆德编译选项的声明需要你去处理。而CxImage类库在这方面做得很好。还有让我最看好的,就是作者完全公开了源代码。相对于那些封装好的图形库和GDI+来说,这一点使我们可以进一步学习各种编解码技术,而不再浮于各种技术的表面。

    CxImage是一个可以用于MFC的C++类,可以打开,保存,显示,转换各种格式的图像文件,比如BMP, JPEG, GIF, PNG, TIFF, MNG, ICO, PCX, TGA, WMF, WBMP, JBG, J2K 等格式的文件。可以实现BMP<->JPG,PNG <>TIFF格式等等的转换。

    既可以实现图像文件的类型转换,也可以实现在内存图像数据的类型转换,并且使用很方便。

    它的作者是: Davide Pizzolato ,主页: http://www.xdp.it/

    首先,到http://www.codeproject.com/bitmap/CXImage.asp 下载它的源文件和Demo例子.

    注: 在Codeproject下载这个类,你得先注册一下,因为这个类可是含金量比较高的,下载量比较大的,当然你也会很高兴成为CodeProject的一名成员的,她不收你的费.授权:

    License

    The class CxImage is free; as for the TIFF, JPEG, PNG and ZLIB libraries : "If you use this source code in a product, acknowledgment is not required but would be appreciated."

    CxImage is open source and licensed under the zlib license . In a nutshell, this means that you can use the code however you wish, as long as you don't claim it as your own.

    由于很多人上codeproject的时候,老是上不去,所以,你也可以去这个类库的作者--Davide Pizzolato的主页去下载

    他的主页还有另外的源代码,有兴趣的也可以看看.

     

    二。编译CxImage类库

    作者已经提供了整个类库配置的工程文件CxImgLib.dsw (VC++6.0),只要打开它进行编译即可。需要大家注意的是:整个CxImage类库非常大。如果你只需要能处理其中的几种格式,编译该类库时,你可以在配置的头文件ximcfg.h 中找到一些编译开关选项来关闭一些图像库。JPG、PNG、TIFF中的每一个库,都会向最终程序增加约100KB的内容。而CxImage类库压缩后只有约60KB。所以,你需要谨慎挑选一些你真正需要的类库。

     

    图片点击可在新窗口打开查看   // 类库配置文件:ximacfg.h
    图片点击可在新窗口打开查看
    #define  CXIMAGE_SUPPORT_JPG 1
    图片点击可在新窗口打开查看
    // 如果要实现bmp->jpg 则必须打开
    图片点击可在新窗口打开查看
    #define  CXIMAGE_SUPPORT_BMP 1
    图片点击可在新窗口打开查看
    #define  CXIMAGE_SUPPORT_GIF 1
    图片点击可在新窗口打开查看
    #define  CXIMAGE_SUPPORT_JPG 1
    图片点击可在新窗口打开查看
    // 以上为必须打开,下面的随便............
    图片点击可在新窗口打开查看
    #define  CXIMAGE_SUPPORT_PNG 0 //不使用它
    图片点击可在新窗口打开查看
    #define  CXIMAGE_SUPPORT_MNG 0
    图片点击可在新窗口打开查看
    #define  CXIMAGE_SUPPORT_ICO 1
    图片点击可在新窗口打开查看
    #define  CXIMAGE_SUPPORT_TIF 0 //
    图片点击可在新窗口打开查看
    #define  CXIMAGE_SUPPORT_TGA 0 //
    图片点击可在新窗口打开查看
    #define  CXIMAGE_SUPPORT_PCX 0 //
    图片点击可在新窗口打开查看
    #define  CXIMAGE_SUPPORT_WBMP 0 //
    图片点击可在新窗口打开查看
    #define  CXIMAGE_SUPPORT_WMF 0 //
    图片点击可在新窗口打开查看
    #define  CXIMAGE_SUPPORT_J2K   //  Beta, use JP2
    图片点击可在新窗口打开查看
    #define  CXIMAGE_SUPPORT_JBG 0
    //.............


    其他的可以不打开

    编译该类库有好几个选择的工程,如下图所示:

    图片点击可在新窗口打开查看

     各工程的作用对应如下:

    • CxImage : cximage.lib - static library
    • CxImageCrtDll : cximagecrt.dll - DLL not using mfc
    • CxImageMfcDll : cximage.dll - DLL using mfc
    • Demo : demo.exe - program linked with cximage.lib and the C libraries
    • DemoDll : demodll.exe - program linked with cximagecrt.dll
    • j2k,jasper,jbig,jpeg,png,tiff,zlib : static C libraries

    编译这些工程需要耗费几分钟的时间(中间文件可达60MB)。

    三。在程序中应用CxImage类库进行图像类型转换

    在你的VC工程中使用这个类库,要对工程进行如下设置(Project Settings):

    |- C/C++
      |- Code Generation
      |   |- Use run-time library : Multithreaded DLL (must be the same for
      |   |  all the linked libraries)  //应该只要是多线程DLL即可,DEBUG的也行
      |   |- Struct member alignment : must be the same for all the linked libraries
      |- Precompiled headers : not using precompiled headers
      |- Preprocessor
          |- Additional Include Directories:  ../cximage(该处填CxImage里的.h和.cpp文件拷贝并导入工程后所在的文件夹,填写后在工程中include时编译器会查找该文件夹,故include的文件无需路径)
    |- Link
        |- General
            |- Object/library modules:  png.lib 
                                                           jpeg.lib 
                                                           zlib.lib 
                                                           tiff.lib 
                                                           jasper.lib 
                                                          cximage.lib  (把需要的lib文件从CxImage中拷贝到工程中的lib文件所在的目录)

    并且从CxImage中将xfile.h、ximacfg.h、ximadef.h、ximage.cpp、ximage.h、xiofile.h、xmemfile.cpp、xmemfile.h拷贝到工程文件夹下并将CxImage.h文件加入工程中即可。也可以设置vc6的"tools"中的"include"路径.

    下面介绍应用它进行图像类型转换的方式:

    1.从一种图像文件类型转换为另一种文件类型(convert from a format to another)

    图片点击可在新窗口打开查看  CxImage  image;    //  定义一个CxImage对象
    图片点击可在新窗口打开查看
    图片点击可在新窗口打开查看
    //  从bmp文件转换为jpg文件(bmp -> jpg)
    图片点击可在新窗口打开查看
    image.Load( " image.bmp " CXIMAGE_FORMAT_BMP);    // 先装载bmp文件,需要指定文件类型
    图片点击可在新窗口打开查看    
    //  判断加载的bmp文件是否存在。
    图片点击可在新窗口打开查看图片点击可在新窗口打开查看
    if  (image.IsValid())... {
    图片点击可在新窗口打开查看       
    // Returns true if the image has 256 colors  and linear grey scale palette.
    图片点击可在新窗口打开查看
        if(!image.IsGrayScale()) image.IncreaseBpp(24);   // param nbit: 4, 8, 24
    图片点击可在新窗口打开查看
        image.SetJpegQuality(99);                // 设置图像的压缩质量参数(从0到100,数值越大,质量越高)
    图片点击可在新窗口打开查看
        image.Save("image.jpg",CXIMAGE_FORMAT_JPG);          // 把压缩后的图像以jpg文件类型保存起来。
    图片点击可在新窗口打开查看
    }

    图片点击可在新窗口打开查看
    图片点击可在新窗口打开查看


    图片点击可在新窗口打开查看 //  从png文件转换为tif文件(png -> tif)
    图片点击可在新窗口打开查看
    image.Load( " image.png " CXIMAGE_FORMAT_PNG);
    图片点击可在新窗口打开查看图片点击可在新窗口打开查看
    if  (image.IsValid()) {
    图片点击可在新窗口打开查看    image.Save(
    "image.tif",CXIMAGE_FORMAT_TIF);
    图片点击可在新窗口打开查看}


    2。加载程序资源图像(load an image resource)

    即从程序的资源图像中构建CxImage对象,有如下几种方式:

     

    图片点击可在新窗口打开查看 //  Load the resource IDR_PNG1 from the PNG resource type
    图片点击可在新窗口打开查看
    CxImage *  newImage  =   new  CxImage();
    图片点击可在新窗口打开查看newImage
    -> LoadResource(FindResource(NULL,MAKEINTRESOURCE(IDR_PNG1),
    图片点击可在新窗口打开查看                       
    " PNG " ),CXIMAGE_FORMAT_PNG);

     

    或者

     

    图片点击可在新窗口打开查看 // Load the resource IDR_JPG1 from DLL
    图片点击可在新窗口打开查看
    CxImage *  newImage  =   new  CxImage();
    图片点击可在新窗口打开查看HINSTANCE hdll
    = LoadLibrary( " imagelib.dll " );
    图片点击可在新窗口打开查看图片点击可在新窗口打开查看
    if  (hdll) {
    图片点击可在新窗口打开查看    HRSRC hres
    =FindResource(hdll,MAKEINTRESOURCE(IDR_JPG1),"JPG");
    图片点击可在新窗口打开查看    newImage
    ->LoadResource(hres,CXIMAGE_FORMAT_JPG,hdll);
    图片点击可在新窗口打开查看    FreeLibrary(hdll);
    图片点击可在新窗口打开查看}

     

    或者

     

    图片点击可在新窗口打开查看 // Load bitmap resource;
    图片点击可在新窗口打开查看
    HBITMAP bitmap  =  ::LoadBitmap(AfxGetInstanceHandle(),
    图片点击可在新窗口打开查看                              MAKEINTRESOURCE(IDB_BITMAP1)));
    图片点击可在新窗口打开查看CxImage 
    * newImage  =   new  CxImage();
    图片点击可在新窗口打开查看newImage
    -> CreateFromHBITMAP(bitmap);

     

    3。在内存缓冲中的图像类型转换

    (1)把内存缓冲中的数据解码成一个Image对象(decode an image from memory)

    有如下几种方式:
    ------

    图片点击可在新窗口打开查看 CxImage image((BYTE * )buffer,size,image_type); // 把内存缓冲buffer中的数据构造成Image对象
    图片点击可在新窗口打开查看
    图片点击可在新窗口打开查看
    // 或:
    图片点击可在新窗口打开查看

    图片点击可在新窗口打开查看CxMemFile memfile((BYTE
    * )buffer,size);  //  显式使用CxMemFile对象
    图片点击可在新窗口打开查看
    CxImage image( & memfile,image_type);
    图片点击可在新窗口打开查看
    图片点击可在新窗口打开查看
    // 或:
    图片点击可在新窗口打开查看

    图片点击可在新窗口打开查看CxMemFile memfile((BYTE
    * )buffer,size);
    图片点击可在新窗口打开查看CxImage
    *  image  =   new  CxImage();
    图片点击可在新窗口打开查看image
    -> Decode( & memfile,type);
    图片点击可在新窗口打开查看

     

    ============

    (2)把Image编码存放到内存缓冲中(encode an image in memory)

    --------

    图片点击可在新窗口打开查看 long  size = 0 ; // 得到图像大小
    图片点击可在新窗口打开查看
    BYTE *  buffer = 0 ; // 存储图像数据的缓冲
    图片点击可在新窗口打开查看
    image.Encode(buffer,size,image_type); // 把image对象中的图像以type类型数据copy到buffer
    图片点击可在新窗口打开查看
    ...
    图片点击可在新窗口打开查看free(buffer);
    图片点击可在新窗口打开查看
    图片点击可在新窗口打开查看或:
    图片点击可在新窗口打开查看
    图片点击可在新窗口打开查看CxMemFile memfile;            
    //  显式使用CxMemFile对象
    图片点击可在新窗口打开查看
    memfile.Open();
    图片点击可在新窗口打开查看image.Encode(
    & memfile,image_type);
    图片点击可在新窗口打开查看BYTE
    *  buffer  =  memfile.GetBuffer();
    图片点击可在新窗口打开查看
    long  size  =  memfile.Size();
    图片点击可在新窗口打开查看...
    图片点击可在新窗口打开查看free(buffer);
    图片点击可在新窗口打开查看



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值