首页 使用libpng读取PNG图片像素数据

使用libpng读取PNG图片像素数据

举报
开通vip

使用libpng读取PNG图片像素数据使用libpng读取PNG图片像素数据 libpng 是一套免费的、公开源代码的程序库,支持对 PNG 图形文件的创建、读写等操作。可以到www.libpng.org  上下载源代码。libpng 使用 zlib 程序库作为压缩引擎,zlib 也是著名的 gzip (GNU zip) 所采用的压缩引擎。zlib 是通用的压缩库,提供了一套 in-memory 压缩和解压函数,并能检测解压出来的数据的完整性(integrity)。zlib 也支持读写 gzip (.gz) 格式的文件这些都是免费和公开的哦。在下载了...

使用libpng读取PNG图片像素数据
使用libpng读取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-1.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路径(这个简单 方法 快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载 相信大家都明白吧)。运行后,就生成了两个静态库了。lib做好以后,就可以将lib加到我们要做的工程中去。在link中设置好,并将png.h和zlib.h都加进去。这样就可以正式的使用libpng了!   下面到重点 内容 财务内部控制制度的内容财务内部控制制度的内容人员招聘与配置的内容项目成本控制的内容消防安全演练内容 了。如何用pnglib实现对文件的读写? 现在让我们来试着写一段代码来读取PNG像素数据(from File or Stream),并把读取的数据存储到一个数组rgba中,用来生成OpenGl纹理   typedef struct {     u8* pixelData;     int imageWidth;     int imageHeight; }ImageInfo;   typedef struct {     u8* data;     int size;     int offset; }ImageSource;   //---------------------------------------------------------------------------------------------------------------- static void pngReaderCallback(png_structp png_ptr, png_bytep data, png_size_t length) {     ImageSource* isource = (ImageSource*)png_get_io_ptr(png_ptr);     if(isource->offset + length <= isource->size)     {        memcpy(data, isource->data + isource->offset, length);        isource->offset += length;     }     else     {         png_error(png_ptr,"pngReaderCallback failed");     } } //---------------------------------------------------------------------------------------------------------------- ImageInfo*  decodePNGFromStream(const u8* pixelData, const u32& dataSize) {     png_structp png_ptr;     png_infop info_ptr;     int width, height, rowBytes;     png_byte color_type;  //可以是PNG_COLOR_TYPE_RGB,PNG_COLOR_TYPE_PALETTE.......等     png_byte bit_depth;     png_colorp palette;     png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,NULL,NULL);     if (!png_ptr)     {         png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);         TFC_DEBUG("ReadPngFile: Failed to create png_ptr");     }     info_ptr = png_create_info_struct(png_ptr);     if (!info_ptr)     {         png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);         TFC_DEBUG("ReadPngFile: Failed to create info_ptr");     }     if (setjmp(png_jmpbuf(png_ptr)))     {         png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);         TFC_DEBUG("ReadPngFile: Failed to read the PNG file");     }     ImageSource imgsource;     imgsource.data = (u8*)pixelData;     imgsource.size = dataSize;     imgsource.offset = 0;     //define our own callback function for I/O instead of reading from a file     png_set_read_fn(png_ptr,&imgsource, pngReaderCallback );     /* **************************************************      * The low-level read interface in libpng (http://www.libpng.org/pub/png/libpng-1.2.5-manual.html)      * **************************************************      */     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;     rowBytes = info_ptr->rowbytes;     palette= info_ptr->palette;     // Convert stuff to appropriate formats!     if(color_type==PNG_COLOR_TYPE_PALETTE)     {         png_set_packing(png_ptr);         png_set_palette_to_rgb(png_ptr); //Expand data to 24-bit RGB or 32-bit RGBA if alpha available.     }     if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)         png_set_gray_1_2_4_to_8(png_ptr);     if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)         png_set_gray_to_rgb(png_ptr);     if (bit_depth == 16)         png_set_strip_16(png_ptr);     //Expand paletted or RGB images with transparency to full alpha channels so the data will be available as RGBA quartets.     if(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))     {         png_set_tRNS_to_alpha(png_ptr);     }     //png_read_update_info(png_ptr, info_ptr);     u8* rgba = new u8[width * height * 4];  //each pixel(RGBA) has 4 bytes     png_bytep * row_pointers;     row_pointers = (png_bytep*)png_malloc(sizeof(png_bytep) * height);     for (int y = 0; y < height; y++)     {         row_pointers[y] = (png_bytep)png_malloc(width<<2); //each pixel(RGBA) has 4 bytes     }     png_read_image(png_ptr, row_pointers);     //unlike store the pixel data from top-left corner, store them from bottom-left corner for OGLES Texture drawing...     int pos = (width * height * 4) - (4 * width);     for(int row = 0; row < height; row++)     {        for(int col = 0; col < (4 * width); col += 4)        {            rgba[pos++] = row_pointers[row][col];        // red            rgba[pos++] = row_pointers[row][col + 1];    // green            rgba[pos++] = row_pointers[row][col + 2];    // blue            rgba[pos++] = row_pointers[row][col + 3];    // alpha        }        pos=(pos - (width * 4)*2); //move the pointer back two rows     }     ImageInfo* imageInfo = (ImageInfo*)kdMalloc(sizeof(ImageInfo));     imageInfo->pixelData = rgba;     imageInfo->imageHeight = height;     imageInfo->imageWidth = width;     //clean up after the read, and free any memory allocated     png_destroy_read_struct(&png_ptr, &info_ptr, NULL);     return imageInfo; } //---------------------------------------------------------------------------------------------------------------- ImageInfo*   decodePNGFromFile(char* fileName) {     char png_header[8];     png_structp png_ptr;     png_infop info_ptr;     int width, height, rowBytes;     png_byte color_type;     png_byte bit_depth;     png_colorp palette;     /* open file and test for it being a png */     FILE *file = fopen(fileName, "rb");     fread(png_header, 1, 8, file);     if(png_sig_cmp((png_bytep)png_header, 0, 8))     {         TFC_DEBUG("Not a PNG file...");         fclose(file);     }     /* initialise structures for reading a png file */     png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);     info_ptr = png_create_info_struct(png_ptr);     if (setjmp(png_jmpbuf(png_ptr)))     {         png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);         TFC_DEBUG("ReadPngFile: Failed to read the PNG file");         fclose(file);     }     //I/O initialisation methods     png_init_io(png_ptr, file);     png_set_sig_bytes(png_ptr, 8);  //Required!!!     /* **************************************************      * The high-level read interface in libpng (http://www.libpng.org/pub/png/libpng-1.2.5-manual.html)      * **************************************************      */        png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND, 0);        width = info_ptr->width;        height = info_ptr->height;        unsigned char* rgba = new unsigned char[width * height * 4];  //each pixel(RGBA) has 4 bytes        png_bytep* row_pointers = png_get_rows(png_ptr, info_ptr);        //Original PNG pixel data stored from top-left corner, BUT OGLES Texture drawing is from bottom-left corner        //int pos = 0;        //for(int row = 0; row < height; row++)        //{            //for(int col = 0; col < (4 * width); col += 4)            //{               //rgba[pos++] = row_pointers[row][col];     // red               //rgba[pos++] = row_pointers[row][col + 1]; // green               //rgba[pos++] = row_pointers[row][col + 2]; // blue               //rgba[pos++] = row_pointers[row][col + 3]; // alpha            //}        //}        //unlike store the pixel data from top-left corner, store them from bottom-left corner for OGLES Texture drawing...        int pos = (width * height * 4) - (4 * width);        for(int row = 0; row < height; row++)        {           for(int col = 0; col < (4 * width); col += 4)           {               rgba[pos++] = row_pointers[row][col];        // red               rgba[pos++] = row_pointers[row][col + 1]; // green               rgba[pos++] = row_pointers[row][col + 2]; // blue               rgba[pos++] = row_pointers[row][col + 3]; // alpha           }           pos=(pos - (width * 4)*2); //move the pointer back two rows        }     ImageInfo* imageInfo = (ImageInfo*)kdMalloc(sizeof(ImageInfo));     imageInfo->pixelData = rgba;     imageInfo->imageHeight = height;     imageInfo->imageWidth = width;     //clean up after the read, and free any memory allocated     png_destroy_read_struct(&png_ptr, &info_ptr, NULL);     fclose(file);     return imageInfo; } //----------------------------------------------------------------------------------------------------------------   int createPNGTextureFromStream(const u8* pixelData, const u32& dataSize) {         GLuint textureID;         glEnable(GL_TEXTURE_2D);         glGenTextures(1,&textureID);         glBindTexture(GL_TEXTURE_2D,textureID);         ImageInfo* imageInfo = decodePNGFromStream(pixelData, dataSize);          glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,imageInfo->imageWidth,imageInfo->imageHeight,0,                                  GL_RGBA,GL_UNSIGNED_BYTE,imageInfo->pixelData);         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);         delete[] imageInfo->pixelData;         delete imageInfo;         return textureID; } //----------------------------------------------------------------------------------------------------------------   void main() {       //Testcase1: decoding png data from a raw png bufferstream and create the corresponding Texture       //假设我们从某个地方可以拿到一个unsigned char* 的PNG数据源pixelData.       int texId = createPNGTextureFromStream(pixelData, dataSize);         //Testcase2: decoding png data from a given png file and and create the corresponding Texture       char* fileName = "example.png";       int texId = createPNGTextureFromFile(fileName);         //现在我们就可以用创建出来的textureID来绘制纹理了。。。。 }   ----------------------------------------------------------- ----------------------------------------------------------- -----------------------------------------------------------   附录  让我们打开pnglib下面的一个example.c   /* Read a PNG file. You may want to return an error code if the read * fails (depending upon the failure). There are two "prototypes" given * here - one where we are given the filename, and we need to open the * file, and the other where we are given an open file (possibly with * some or all of the magic bytes read - see comments above). */ #ifdef open_file /* prototype 1 */ void read_png(char *file_name) /* We need to open the file */ { 定义两个很重要的pngwen文件指针。png_info里面放的是pngchuck和png的数据。 png_structp png_ptr; png_infop info_ptr; 这些是读出图像需要的参数,图像高。宽、深度、图像类型、交错类型。 unsigned int sig_read = 0; png_uint_32 width, height; int bit_depth, color_type, interlace_type; FILE *fp; 打开文件,把文件指针给png_prt if ((fp = fopen(file_name, "rb")) == NULL) return (ERROR); #else no_open_file /* prototype 2 */ void read_png(FILE *fp, unsigned int sig_read) /* file is already open */ { png_structp png_ptr; png_infop info_ptr; png_uint_32 width, height; int bit_depth, color_type, interlace_type; #endif no_open_file /* only use one prototype! */ /* Create and initialize the png_struct with the desired error handler * functions. If you want to use the default stderr and longjump method, * you can supply NULL for the last three parameters. We also supply the * the compiler header file version, so that we know if the application * was compiled with a compatible version of the library. REQUIRED */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, png_voidp user_error_ptr, user_error_fn, user_warning_fn); if (png_ptr == NULL) { fclose(fp); return (ERROR); } /* Allocate/initialize the memory for image information. REQUIRED. */ info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { fclose(fp); png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); return (ERROR); } /* Set error handling if you are using the setjmp/longjmp method (this is * the normal method of doing things with libpng). REQUIRED unless you * set up your own error handlers in the png_create_read_struct() earlier. */ if (setjmp(png_jmpbuf(png_ptr))) { /* Free all of the memory associated with the png_ptr and info_ptr */ png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); fclose(fp); /* If we get here, we had a problem reading the file */ return (ERROR); } /* One of the following I/O initialization methods is REQUIRED */ #ifdef streams /* PNG file I/O method 1 */ /* Set up the input control if you are using standard C streams */ png_init_io(png_ptr, fp); #else no_streams /* PNG file I/O method 2 */ /* If you are using replacement read functions, instead of calling * png_init_io() here you would call: */ png_set_read_fn(png_ptr, (void *)user_io_ptr, user_read_fn); /* where user_io_ptr is a structure you want available to the callbacks */ #endif no_streams /* Use only one I/O method! */ /* If we have already read some of the signature */ png_set_sig_bytes(png_ptr, sig_read); #ifdef hilevel /* * If you have enough memory to read in the entire image at once, * and you need to specify only transforms that can be controlled * with one of the PNG_TRANSFORM_* bits (this presently excludes * dithering, filling, setting background, and doing gamma * adjustment), then you can read the entire image (including * pixels) into the info structure with this call: */ png_read_png(png_ptr, info_ptr, png_transforms, png_voidp_NULL); #else /* OK, you're doing it the hard way, with the lower-level functions */ /* The call to png_read_info() gives us all of the information from the * PNG file before the first IDAT (image data chunk). REQUIRED */ png_read_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, int_p_NULL, int_p_NULL); /* Set up the data transformations you want. Note that these are all * optional. Only call them if you want/need them. Many of the * transformations only work on specific types of images, and many * are mutually exclusive. */ /* tell libpng to strip 16 bit/color files down to 8 bits/color */ png_set_strip_16(png_ptr); /* Strip alpha bytes from the input data without combining with the * background (not recommended). */ png_set_strip_alpha(png_ptr); /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single * byte into separate bytes (useful for paletted and grayscale images). */ png_set_packing(png_ptr); /* Change the order of packed pixels to least significant bit first * (not useful if you are using png_set_packing). */ png_set_packswap(png_ptr); /* Expand paletted colors into true RGB triplets */ if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_rgb(png_ptr); /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */ if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_gray_1_2_4_to_8(png_ptr); /* Expand paletted or RGB images with transparency to full alpha channels * so the data will be available as RGBA quartets. */ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr); /* Set the background color to draw transparent and alpha images over. * It is possible to set the red, green, and blue components directly * for paletted images instead of supplying a palette index. Note that * even if the PNG file supplies a background, you are not required to * use it - you should use the (solid) application background if it has one. */ png_color_16 my_background, *image_background; if (png_get_bKGD(png_ptr, info_ptr, &image_background)) png_set_background(png_ptr, image_background, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); else png_set_background(png_ptr, &my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); /* Some suggestions as to how to get a screen gamma value */ /* Note that screen gamma is the display_exponent, which includes * the CRT_exponent and any correction for viewing conditions */ if (/* We have a user-defined screen gamma value */) { screen_gamma = user-defined screen_gamma; } /* This is one way that applications share the same screen gamma value */ else if ((gamma_str = getenv("SCREEN_GAMMA")) != NULL) { screen_gamma = atof(gamma_str); } /* If we don't have another value */ else { screen_gamma = 2.2; /* A good guess for a PC monitors in a dimly lit room */ screen_gamma = 1.7 or 1.0; /* A good guess for Mac systems */ } /* Tell libpng to handle the gamma conversion for you. The final call * is a good guess for PC generated images, but it should be configurable * by the user at run time by the user. It is strongly suggested that * your application support gamma correction. */ int intent; if (png_get_sRGB(png_ptr, info_ptr, &intent)) png_set_gamma(png_ptr, screen_gamma, 0.45455); else { double image_gamma; if (png_get_gAMA(png_ptr, info_ptr, &image_gamma)) png_set_gamma(png_ptr, screen_gamma, image_gamma); else png_set_gamma(png_ptr, screen_gamma, 0.45455); } /* Dither RGB files down to 8 bit palette or reduce palettes * to the number of colors available on your screen. */ if (color_type & PNG_COLOR_MASK_COLOR) { int num_palette; png_colorp palette; /* This reduces the image to the application supplied palette */ if (/* we have our own palette */) { /* An array of colors to which the image should be dithered */ png_color std_color_cube[MAX_SCREEN_COLORS]; png_set_dither(png_ptr, std_color_cube, MAX_SCREEN_COLORS, MAX_SCREEN_COLORS, png_uint_16p_NULL, 0); } /* This reduces the image to the palette supplied in the file */ else if (png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette)) { png_uint_16p histogram = NULL; png_get_hIST(png_ptr, info_ptr, &histogram); png_set_dither(png_ptr, palette, num_palette, max_screen_colors, histogram, 0); } } /* invert monochrome files to have 0 as white and 1 as black */ png_set_invert_mono(png_ptr); /* If you want to shift the pixel values from the range [0,255] or * [0,65535] to the original [0,7] or [0,31], or whatever range the * colors were originally in: */ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT)) { png_color_8p sig_bit; png_get_sBIT(png_ptr, info_ptr, &sig_bit); png_set_shift(png_ptr, sig_bit); } /* flip the RGB pixels to BGR (or RGBA to BGRA) */ if (color_type & PNG_COLOR_MASK_COLOR) png_set_bgr(png_ptr); /* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */ png_set_swap_alpha(png_ptr); /* swap bytes of 16 bit files to least significant byte first */ png_set_swap(png_ptr); /* Add filler (or alpha) byte (before/after each RGB triplet) */ png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); /* Turn on interlace handling. REQUIRED if you are not using * png_read_image(). To see how to handle interlacing passes, * see the png_read_row() method below: */ number_passes = png_set_interlace_handling(png_ptr); /* Optional call to gamma correct and add the background to the palette * and update info structure. REQUIRED if you are expecting libpng to * update the palette for you (ie you selected such a transform above). */ png_read_update_info(png_ptr, info_ptr); /* Allocate the memory to hold the image using the fields of info_ptr. */ /* The easiest way to read the image: */ png_bytep row_pointers[height]; for (row = 0; row < height; row++) { row_pointers[row] = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); } /* Now it's time to read the image. One of these methods is REQUIRED */ #ifdef entire /* Read the entire image in one go */ png_read_image(png_ptr, row_pointers); #else no_entire /* Read the image one or more scanlines at a time */ /* The other way to read images - deal with interlacing: */ for (pass = 0; pass < number_passes; pass++) { #ifdef single /* Read the image a single row at a time */ for (y = 0; y < height; y++) { png_read_rows(png_ptr, &
本文档为【使用libpng读取PNG图片像素数据】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_989247
暂无简介~
格式:doc
大小:53KB
软件:Word
页数:22
分类:互联网
上传时间:2013-04-27
浏览量:65