以下是读取PNG图片的图像数据的代码,如果你要使用该代码,请补充剩余代码。
- #include <png.h>
- #define PNG_BYTES_TO_CHECK 4
- int load_png_image( const char *filepath, /* 其它参数 */ )
- {
- FILE *fp;
- png_structp png_ptr;
- png_infop info_ptr;
- png_bytep* row_pointers;
- char buf[PNG_BYTES_TO_CHECK];
- int w, h, x, y, temp, color_type;
- fp = fopen( filepath, "rb" );
- if( fp == NULL ) {
- return /* 你的返回值 */;
- }
- png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0 );
- info_ptr = png_create_info_struct( png_ptr );
- setjmp( png_jmpbuf(png_ptr) );
- /* 读取PNG_BYTES_TO_CHECK个字节的数据 */
- temp = fread( buf, 1, PNG_BYTES_TO_CHECK, fp );
- /* 若读到的数据并没有PNG_BYTES_TO_CHECK个字节 */
- if( temp < PNG_BYTES_TO_CHECK ) {
- fclose(fp);
- png_destroy_read_struct( &png_ptr, &info_ptr, 0);
- return /* 你的返回值 */;
- }
- /* 检测数据是否为PNG的签名 */
- temp = png_sig_cmp( (png_bytep)buf, (png_size_t)0, PNG_BYTES_TO_CHECK );
- /* 如果不是PNG的签名,则说明该文件不是PNG文件 */
- if( temp != 0 ) {
- fclose(fp);
- png_destroy_read_struct( &png_ptr, &info_ptr, 0);
- return /* 你的返回值 */;
- }
- /* 复位文件指针 */
- rewind( fp );
- /* 开始读文件 */
- png_init_io( png_ptr, fp );
- /* 读取PNG图片信息 */
- png_read_png( png_ptr, info_ptr, PNG_TRANSFORM_EXPAND, 0 );
- /* 获取图像的色彩类型 */
- color_type = png_get_color_type( png_ptr, info_ptr );
- /* 获取图像的宽高 */
- w = png_get_image_width( png_ptr, info_ptr );
- h = png_get_image_height( png_ptr, info_ptr );
- /* 获取图像的所有行像素数据,row_pointers里边就是rgba数据 */
- row_pointers = png_get_rows( png_ptr, info_ptr );
- /* 根据不同的色彩类型进行相应处理 */
- switch( color_type ) {
- case PNG_COLOR_TYPE_RGB_ALPHA:
- for( y=0; y<h; ++y ) {
- for( x=0; x<w*4; ) {
- /* 以下是RGBA数据,需要你自己补充代码,保存RGBA数据 */
- /* 目标内存 */ = row_pointers[y][x++]; // red
- /* 目标内存 */ = row_pointers[y][x++]; // green
- /* 目标内存 */ = row_pointers[y][x++]; // blue
- /* 目标内存 */ = row_pointers[y][x++]; // alpha
- }
- }
- break;
- case PNG_COLOR_TYPE_RGB:
- for( y=0; y<h; ++y ) {
- for( x=0; x<w*3; ) {
- /* 目标内存 */ = row_pointers[y][x++]; // red
- /* 目标内存 */ = row_pointers[y][x++]; // green
- /* 目标内存 */ = row_pointers[y][x++]; // blue
- }
- }
- break;
- /* 其它色彩类型的图像就读了 */
- default:
- fclose(fp);
- png_destroy_read_struct( &png_ptr, &info_ptr, 0);
- return /* 你的返回值 */;
- }
- png_destroy_read_struct( &png_ptr, &info_ptr, 0);
- return 0;
- }
#include <png.h>
#define PNG_BYTES_TO_CHECK 4
int load_png_image( const char *filepath, /* 其它参数 */ )
{
FILE *fp;
png_structp png_ptr;
png_infop info_ptr;
png_bytep* row_pointers;
char buf[PNG_BYTES_TO_CHECK];
int w, h, x, y, temp, color_type;
fp = fopen( filepath, "rb" );
if( fp == NULL ) {
return /* 你的返回值 */;
}
png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0 );
info_ptr = png_create_info_struct( png_ptr );
setjmp( png_jmpbuf(png_ptr) );
/* 读取PNG_BYTES_TO_CHECK个字节的数据 */
temp = fread( buf, 1, PNG_BYTES_TO_CHECK, fp );
/* 若读到的数据并没有PNG_BYTES_TO_CHECK个字节 */
if( temp < PNG_BYTES_TO_CHECK ) {
fclose(fp);
png_destroy_read_struct( &png_ptr, &info_ptr, 0);
return /* 你的返回值 */;
}
/* 检测数据是否为PNG的签名 */
temp = png_sig_cmp( (png_bytep)buf, (png_size_t)0, PNG_BYTES_TO_CHECK );
/* 如果不是PNG的签名,则说明该文件不是PNG文件 */
if( temp != 0 ) {
fclose(fp);
png_destroy_read_struct( &png_ptr, &info_ptr, 0);
return /* 你的返回值 */;
}
/* 复位文件指针 */
rewind( fp );
/* 开始读文件 */
png_init_io( png_ptr, fp );
/* 读取PNG图片信息 */
png_read_png( png_ptr, info_ptr, PNG_TRANSFORM_EXPAND, 0 );
/* 获取图像的色彩类型 */
color_type = png_get_color_type( png_ptr, info_ptr );
/* 获取图像的宽高 */
w = png_get_image_width( png_ptr, info_ptr );
h = png_get_image_height( png_ptr, info_ptr );
/* 获取图像的所有行像素数据,row_pointers里边就是rgba数据 */
row_pointers = png_get_rows( png_ptr, info_ptr );
/* 根据不同的色彩类型进行相应处理 */
switch( color_type ) {
case PNG_COLOR_TYPE_RGB_ALPHA:
for( y=0; y<h; ++y ) {
for( x=0; x<w*4; ) {
/* 以下是RGBA数据,需要你自己补充代码,保存RGBA数据 */
/* 目标内存 */ = row_pointers[y][x++]; // red
/* 目标内存 */ = row_pointers[y][x++]; // green
/* 目标内存 */ = row_pointers[y][x++]; // blue
/* 目标内存 */ = row_pointers[y][x++]; // alpha
}
}
break;
case PNG_COLOR_TYPE_RGB:
for( y=0; y<h; ++y ) {
for( x=0; x<w*3; ) {
/* 目标内存 */ = row_pointers[y][x++]; // red
/* 目标内存 */ = row_pointers[y][x++]; // green
/* 目标内存 */ = row_pointers[y][x++]; // blue
}
}
break;
/* 其它色彩类型的图像就读了 */
default:
fclose(fp);
png_destroy_read_struct( &png_ptr, &info_ptr, 0);
return /* 你的返回值 */;
}
png_destroy_read_struct( &png_ptr, &info_ptr, 0);
return 0;
}
以下是生成png图片文件的代码:
- int write_png_file(char *file_name , pic_data *graph)
- /* 将puc_data结构中的数据写入至png文件 */
- {
- int j, i, temp, pos;
- png_byte color_type;
- png_structp png_ptr;
- png_infop info_ptr;
- png_bytep * row_pointers;
- /* create file */
- FILE *fp = fopen(file_name, "wb");
- if (!fp)
- {
- printf("[write_png_file] File %s could not be opened for writing", file_name);
- return -1;
- }
- /* initialize stuff */
- png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
- if (!png_ptr)
- {
- printf("[write_png_file] png_create_write_struct failed");
- return -1;
- }
- info_ptr = png_create_info_struct(png_ptr);
- if (!info_ptr)
- {
- printf("[write_png_file] png_create_info_struct failed");
- return -1;
- }
- if (setjmp(png_jmpbuf(png_ptr)))
- {
- printf("[write_png_file] Error during init_io");
- return -1;
- }
- png_init_io(png_ptr, fp);
- /* write header */
- if (setjmp(png_jmpbuf(png_ptr)))
- {
- printf("[write_png_file] Error during writing header");
- return -1;
- }
- /* 判断要写入至文件的图片数据是否有透明度,来选择色彩类型 */
- if(graph->flag == HAVE_ALPHA) color_type = PNG_COLOR_TYPE_RGB_ALPHA;
- else color_type = PNG_COLOR_TYPE_RGB;
- png_set_IHDR(png_ptr, info_ptr, graph->width, graph->height,
- graph->bit_depth, color_type, PNG_INTERLACE_NONE,
- PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
- png_write_info(png_ptr, info_ptr);
- /* write bytes */
- if (setjmp(png_jmpbuf(png_ptr)))
- {
- printf("[write_png_file] Error during writing bytes");
- return -1;
- }
- if(graph->flag == HAVE_ALPHA) temp = (4 * graph->width);
- else temp = (3 * graph->width);
- pos = 0;
- row_pointers = (png_bytep*)malloc(graph->height*sizeof(png_bytep));
- for(i = 0; i < graph->height; i++)
- {
- row_pointers[i] = (png_bytep)malloc(sizeof(unsigned char)*temp);
- for(j = 0; j < temp; j += 4)
- {
- row_pointers[i][j] = graph->rgba[0][pos]; // red
- row_pointers[i][j+1] = graph->rgba[1][pos]; // green
- row_pointers[i][j+2] = graph->rgba[2][pos]; // blue
- if(graph->flag == HAVE_ALPHA)
- row_pointers[i][j+3] = graph->rgba[3][pos]; // alpha
- ++pos;
- }
- }
- png_write_image(png_ptr, row_pointers);
- /* end write */
- if (setjmp(png_jmpbuf(png_ptr)))
- {
- printf("[write_png_file] Error during end of write");
- return -1;
- }
- png_write_end(png_ptr, NULL);
- /* cleanup heap allocation */
- for (j=0; j<graph->height; j++)
- free(row_pointers[j]);
- free(row_pointers);
- fclose(fp);
- return 0;
- }
int write_png_file(char *file_name , pic_data *graph)
/* 将puc_data结构中的数据写入至png文件 */
{
int j, i, temp, pos;
png_byte color_type;
png_structp png_ptr;
png_infop info_ptr;
png_bytep * row_pointers;
/* create file */
FILE *fp = fopen(file_name, "wb");
if (!fp)
{
printf("[write_png_file] File %s could not be opened for writing", file_name);
return -1;
}
/* initialize stuff */
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr)
{
printf("[write_png_file] png_create_write_struct failed");
return -1;
}
info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
{
printf("[write_png_file] png_create_info_struct failed");
return -1;
}
if (setjmp(png_jmpbuf(png_ptr)))
{
printf("[write_png_file] Error during init_io");
return -1;
}
png_init_io(png_ptr, fp);
/* write header */
if (setjmp(png_jmpbuf(png_ptr)))
{
printf("[write_png_file] Error during writing header");
return -1;
}
/* 判断要写入至文件的图片数据是否有透明度,来选择色彩类型 */
if(graph->flag == HAVE_ALPHA) color_type = PNG_COLOR_TYPE_RGB_ALPHA;
else color_type = PNG_COLOR_TYPE_RGB;
png_set_IHDR(png_ptr, info_ptr, graph->width, graph->height,
graph->bit_depth, color_type, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
png_write_info(png_ptr, info_ptr);
/* write bytes */
if (setjmp(png_jmpbuf(png_ptr)))
{
printf("[write_png_file] Error during writing bytes");
return -1;
}
if(graph->flag == HAVE_ALPHA) temp = (4 * graph->width);
else temp = (3 * graph->width);
pos = 0;
row_pointers = (png_bytep*)malloc(graph->height*sizeof(png_bytep));
for(i = 0; i < graph->height; i++)
{
row_pointers[i] = (png_bytep)malloc(sizeof(unsigned char)*temp);
for(j = 0; j < temp; j += 4)
{
row_pointers[i][j] = graph->rgba[0][pos]; // red
row_pointers[i][j+1] = graph->rgba[1][pos]; // green
row_pointers[i][j+2] = graph->rgba[2][pos]; // blue
if(graph->flag == HAVE_ALPHA)
row_pointers[i][j+3] = graph->rgba[3][pos]; // alpha
++pos;
}
}
png_write_image(png_ptr, row_pointers);
/* end write */
if (setjmp(png_jmpbuf(png_ptr)))
{
printf("[write_png_file] Error during end of write");
return -1;
}
png_write_end(png_ptr, NULL);
/* cleanup heap allocation */
for (j=0; j<graph->height; j++)
free(row_pointers[j]);
free(row_pointers);
fclose(fp);
return 0;
}
这个代码是从libpng给的示例代码中修改而来的,你可以参考一下。
代码没测试,如果有错误请自己修改,如有疑惑,请参考互联网上的其它相关文章,libpng源码包里也有示例程序可以参考。
相关文章: