if (!info_ptr) { png_destroy_read_struct(&png_ptr, NULL, NULL); pbImage=NULL; return FALSE; }
Try
{
#if !defined(PNG_NO_STDIO)
png_init_io(png_ptr, pfFile); //初始化png结构体
#else
png_set_read_fn(png_ptr, (png_voidp)pfFile, png_read_data);
#endif
png_set_sig_bytes(png_ptr, 8); //设置PNG文件署名
png_read_info(png_ptr, info_ptr); //读取PNG信息
png_get_IHDR(png_ptr, info_ptr, (unsigned long *) &cxImgSize, (unsigned long *)&cyImgSize, &iBitDepth, &iColorType, NULL, NULL, NULL); //获取宽度、高度、颜色深度、颜色类型等信息
//将图像数据扩展成每个像素由3个8比特组成
if (iBitDepth == 16) png_set_strip_16(png_ptr);
if (iColorType == PNG_COLOR_TYPE_PALETTE) png_set_expand(png_ptr);
if (iBitDepth < 8) png_set_expand(png_ptr);
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_expand(png_ptr);
if (iColorType == PNG_COLOR_TYPE_GRAY || iColorType == PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb(png_ptr);
if (png_get_bKGD(png_ptr, info_ptr, &pBackground)) //设置背景透明颜色,
{ png_set_background(png_ptr, pBackground, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
bkgColor.red = (byte) pBackground->red;
bkgColor.green = (byte) pBackground->green;
bkgColor.blue = (byte) pBackground->blue;
} else {bkgColor.red=0;bkgColor.green=0; bkgColor.blue =0; }
//判断是否需要gamma转换
if (png_get_gAMA(png_ptr, info_ptr, &dGamma)) png_set_gamma(png_ptr, (double) 2.2, dGamma);
png_read_update_info(png_ptr, info_ptr); //变换后,需要更新info_ptr
png_get_IHDR(png_ptr, info_ptr,(unsigned long *) &cxImgSize, (unsigned long *)&cyImgSize, &iBitDepth, &iColorType, NULL, NULL, NULL); //获取宽度、高度、颜色类型、颜色深度等信息
ulRowBytes = png_get_rowbytes(png_ptr, info_ptr); //行字节数
ulChannels = png_get_channels(png_ptr, info_ptr); //通道信息
cImgChannels = ulChannels;
if (pbImage!=NULL) { free(pbImage); pbImage=NULL; }//空间已经存在,则先释放空间
if ((pbImage = (png_byte *) malloc(ulRowBytes * cyImgSize * sizeof(png_byte))) == NULL)
{ png_error(png_ptr, "Load PNG: Out of memory"); }
if ((ppbRowPointers = (png_bytepp) malloc(cyImgSize * sizeof(png_bytep))) == NULL) //分配内存空间
{ png_error(png_ptr, "Load PNG: Out of memory"); }
for (i = 0; i < cyImgSize; i++) ppbRowPointers[i] = pbImage + i * ulRowBytes; // 设置PNG图像的每行地址
png_read_image(png_ptr, ppbRowPointers); //一次读入图像信息
png_read_end(png_ptr, NULL); //读取辅助块(additional chunks)信息
free (ppbRowPointers); //释放内存空间
ppbRowPointers = NULL;
} Catch (msg)
{ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
pbImage=NULL;
if(ppbRowPointers) free (ppbRowPointers);
fclose(pfFile);
return FALSE;
}
fclose (pfFile);
FillBitmapInfo(); //填充Bitmap信息
bool ret=PngToBitmap(); //将Png图像数据转换成位图数据
return ret;
}
PngSaveImage实现将内存图像数据保存为文件名为pstrFileName的PNG图像,如果执行成功,函数返回TRUE,失败则返回FALSE。
BOOL MyPNG::PngSaveImage (const char * pstrFileName)
{
const int ciBitDepth = 8, ciChannels = 3;
FILE *pfFile; png_uint_32 ulRowBytes; static png_byte **ppbRowPointers = NULL;
int i, iWidth,iHeight;
iWidth=cxImgSize; iHeight=cyImgSize;
if (!pstrFileName) return FALSE; // 文件指针为空则返回
if (!(pfFile = fopen(pstrFileName, "wb"))) return FALSE; //创建文件
// 创建标准的 PNG 结构信息
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,
(png_error_ptr)png_cexcept_error, (png_error_ptr)NULL);
if (!png_ptr) { fclose(pfFile); return FALSE; }
info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) { fclose(pfFile); png_destroy_write_struct(&png_ptr, (png_infopp) NULL); return FALSE; }
Try
{
#if !defined(PNG_NO_STDIO)
png_init_io(png_ptr, pfFile); //初始化 png 结构体信息
#else
png_set_write_fn(png_ptr, (png_voidp)pfFile, png_write_data, png_flush);
#endif
png_set_IHDR(png_ptr, info_ptr, iWidth, iHeight, ciBitDepth,
PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
PNG_FILTER_TYPE_BASE); //写入每像素3比特的PNG图像
png_write_info(png_ptr, info_ptr); //写入文件头信息
png_set_bgr(png_ptr); //将BGR次序转换为RGB次序
ulRowBytes = iWidth * ciChannels; // 每行的字节数
if ((ppbRowPointers = (png_bytepp) malloc(iHeight * sizeof(png_bytep))) == NULL)
Throw "MyPNG: Out of memory"; //分配内存失败;
//设置每行的指针地址
for (i = 0; i < iHeight; i++) ppbRowPointers[i] = pPixelBuffer + (iHeight-1-i) * (((ulRowBytes + 3) >> 2) << 2);
png_write_image (png_ptr, ppbRowPointers); // 一次写入整幅图像
png_write_end(png_ptr, info_ptr); // 写辅助块信息
free (ppbRowPointers); //释放空间
ppbRowPointers = NULL;
png_destroy_write_struct(&png_ptr, (png_infopp) NULL); //写操作结束,释放空间
} Catch (msg)
{ png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
if(ppbRowPointers) free (ppbRowPointers);
fclose(pfFile);
return FALSE;
}
fclose (pfFile);
return TRUE;
}
|