📄 png.cpp
字号:
#include "stdafx.h"
#include "..\..\Include\Pic\Image.h"
extern "C"
{
#include "..\..\Lib\png\png.h"
}
//===================================================================
static void __foo_png_read_data (png_structp png_ptr, png_bytep data, png_size_t length)
{
::CopyMemory (data, png_ptr->io_ptr, length) ;
png_ptr->io_ptr = (BYTE *)png_ptr->io_ptr + length ;
}
static void __foo_png_write_data (png_structp png_ptr, png_bytep data, png_size_t length)
{
::CopyMemory (png_ptr->io_ptr, data, length) ;
png_ptr->io_ptr = (BYTE *)png_ptr->io_ptr + length ;
}
//===================================================================
BOOL FCImage::LoadPng (PCTSTR szFileName)
{
BOOL bRet = FALSE ;
BYTE * pStart = NULL ;
HANDLE hMap = NULL ;
HANDLE hFile = INVALID_HANDLE_VALUE ;
if (pFooDib->hBitmap != NULL)
this->Unload () ;
// mapping the image file
pStart = this->__fooImageReadFile (szFileName, &hFile, &hMap) ;
if (pStart != NULL)
bRet = this->LoadPng (pStart) ; // 读文件
this->__fooImageUnmapFile ((BYTE *)pStart, hMap, hFile) ;
return bRet ;
}
//===================================================================
BOOL FCImage::LoadPng (PCTSTR resName, PCTSTR resType)
{
HRSRC res = ::FindResource (NULL, resName, resType) ;
HGLOBAL gol = ::LoadResource (NULL, res) ;
BYTE * pPngData = (BYTE *) ::LockResource (gol) ;
return (pPngData == NULL) ? FALSE : this->LoadPng (pPngData) ;
}
//===================================================================
BOOL FCImage::LoadPng (BYTE * pStart)
{
BOOL bRet = FALSE ;
png_struct * png_ptr = NULL ; // png Lib
png_info * info_ptr = NULL ; // png Lib
__try
{
// 分配PNG结构,并初始化
png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, (void *)NULL, NULL, NULL) ;
if (png_ptr == NULL)
__leave ;
// 创建PNG信息头
info_ptr = png_create_info_struct (png_ptr) ;
if (info_ptr == NULL)
__leave ;
// 自定义读取函数
png_set_read_fn (png_ptr, pStart, __foo_png_read_data) ;
// 读png文件信息
png_read_info (png_ptr, info_ptr) ;
// 带alpha通道的灰度图
if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
__leave ;
// 16bits/channel == >8bits/channel
if (info_ptr->bit_depth == 16)
png_set_strip_16 (png_ptr) ;
int pixel_depth = info_ptr->pixel_depth ;
if (pixel_depth == 16 ) pixel_depth = 8 ;
// 创建DIB
if (!this->Create (info_ptr->width, info_ptr->height, pixel_depth))
__leave ;
if (info_ptr->num_palette > 0)
{
// 设置调色板
if (info_ptr->num_palette > 256)
__leave ;
RGBQUAD * pPal = new RGBQUAD[info_ptr->num_palette] ;
// RGB ==> RGBQUAD
for (int i = 0 ; i < (int)info_ptr->num_palette ; i++)
{
pPal[i].rgbBlue = info_ptr->palette[i].blue ;
pPal[i].rgbGreen = info_ptr->palette[i].green ;
pPal[i].rgbRed = info_ptr->palette[i].red ;
}
this->SetColorTable (0, info_ptr->num_palette, pPal) ;
delete[] pPal ;
}
else
if (info_ptr->bit_depth == 2) // needed for 2 bpp grayscale PNGs
{
RGBQUAD pal[4] = {{0,0,0,0}, {1,85,85,85}, {2,170,170,170}, {3,255,255,255}} ;
this->SetColorTable (0, 4, pal) ;
}
else
this->SetGrayPalette () ; // needed for grayscale PNGs
// 将tRNS通道转换为alpha通道
if (png_get_valid (png_ptr, info_ptr,PNG_INFO_tRNS))
png_set_tRNS_to_alpha (png_ptr) ;
// 设置为BGR-order
png_set_bgr(png_ptr);
png_read_update_info (png_ptr, info_ptr) ;
// 读取图像数据
png_start_read_image (png_ptr) ;
png_read_image (png_ptr, (png_bytepp)pFooDib->ppLine) ;
png_read_end (png_ptr, info_ptr) ;
bRet = TRUE ;
}
__finally
{
if ((png_ptr != NULL) || (info_ptr != NULL))
png_destroy_read_struct (&png_ptr, &info_ptr, (png_infopp)NULL) ;
}
return bRet ;
}
//===================================================================
BOOL FCImage::SavePng (PCTSTR szFileName, bool bInterlace)
{
BOOL bRet = FALSE ;
HANDLE hMap = NULL ;
HANDLE hFile = INVALID_HANDLE_VALUE ;
BYTE * pStart = NULL ;
png_struct * png_ptr =NULL ;
png_info * info_ptr =NULL ;
__try
{
if ((this->GetHandle () == NULL) || (this->ColorBits() == 16))
__leave ;
// 分配PNG结构,并初始化
png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, (void *)NULL, NULL, NULL) ;
if (png_ptr == NULL)
__leave ;
// 创建PNG信息头
info_ptr = png_create_info_struct (png_ptr) ;
if (info_ptr == NULL)
__leave ;
// 创建文件
pStart = this->__fooImageSaveFile (szFileName, &hFile, &hMap, this->GetPitch() * this->Height()) ;
if (pStart == NULL)
__leave ;
// 自定义写函数
png_set_write_fn (png_ptr, pStart, __foo_png_write_data, NULL) ;
// 设置文件信息
info_ptr->width = this->Width () ;
info_ptr->height = this->Height () ;
info_ptr->pixel_depth = this->ColorBits () ;
info_ptr->channels = (this->ColorBits () == 32) ? 4 : ((this->ColorBits () > 8) ? 3 : 1) ;
info_ptr->bit_depth = this->ColorBits () / info_ptr->channels ;
switch (this->ColorBits ())
{
case 32 :
info_ptr->color_type = PNG_COLOR_TYPE_RGBA ; break ;
case 16 :
case 24 :
info_ptr->color_type = PNG_COLOR_TYPE_RGB ; break ;
default :
info_ptr->color_type = PNG_COLOR_TYPE_PALETTE ; break ;
}
info_ptr->compression_type = info_ptr->filter_type = 0 ;
info_ptr->valid = 0 ;
info_ptr->interlace_type = bInterlace ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE ;
info_ptr->rowbytes = this->GetPitch () ;
// 设置PNG文件信息头
png_set_IHDR(png_ptr, info_ptr,
info_ptr->width, info_ptr->height,
info_ptr->bit_depth, info_ptr->color_type,
info_ptr->interlace_type,
info_ptr->compression_type,
info_ptr->filter_type) ;
// 设置调色板
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
{
RGBQUAD * pPal = new RGBQUAD[1 << this->ColorBits()] ;
BYTE * pPngPal = (BYTE *) pPal ;
this->GetColorTable (0, 1 << this->ColorBits(), pPal) ;
// RGBQUAD ==> RGB
for (int i = 0 ; i < 1 << this->ColorBits() ; i++)
{
MoveMemory (pPngPal, &pPal[i].rgbBlue, 3) ;
char temp ;
temp = pPngPal[2] ;
pPngPal[2] = pPngPal[0] ;
pPngPal[0] = temp ;
pPngPal += 3 ;
}
png_set_PLTE (png_ptr, info_ptr, (png_colorp)pPal, 1 << this->ColorBits()) ;
delete[] pPal ;
}
else
png_set_PLTE (png_ptr, info_ptr, (png_colorp)NULL, 0) ;
// 将信息写入信息头
png_write_info (png_ptr, info_ptr) ;
// 写文件
// 设置为BGR-order
png_set_bgr(png_ptr);
png_write_image (png_ptr, (png_bytepp)pFooDib->ppLine) ;
png_write_end (png_ptr, info_ptr) ;
bRet = TRUE ;
}
__finally
{
if (pStart != NULL) ::UnmapViewOfFile (pStart) ;
if (hMap != NULL)
{
::CloseHandle (hMap) ;
::SetFilePointer (hFile, (BYTE *)png_ptr->io_ptr - pStart, NULL, FILE_BEGIN) ;
::SetEndOfFile (hFile) ; // 设置文件大小
}
if (hFile != INVALID_HANDLE_VALUE) ::CloseHandle (hFile) ;
if (png_ptr != NULL)
png_destroy_write_struct (&png_ptr, (png_infopp)&info_ptr) ;
}
return bRet ;
}
//===================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -