⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 png.cpp

📁 一个国人自己实现图像库的程序(有参考价值)
💻 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 + -