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

📄 gimage.cpp

📁 一个非常有用的开源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/*	Copyright (C) 2006, Mike Gashler	This library is free software; you can redistribute it and/or	modify it under the terms of the GNU Lesser General Public	License as published by the Free Software Foundation; either	version 2.1 of the License, or (at your option) any later version.	see http://www.gnu.org/copyleft/lesser.html*/#include "GImage.h"#include "GBitTable.h"#include <math.h>#include "GMacros.h"#include <stdlib.h>#include "GCompress.h"#include "GBezier.h"#include "GRayTrace.h"#include "GHardFont.h"#include "GPNG.h"#include "GBits.h"#include "GFile.h"#ifdef WIN32#include <windows.h>#else // WIN32typedef unsigned int DWORD;typedef long LONG;typedef short WORD;#pragma pack(1)typedef struct tagBITMAPINFOHEADER {    DWORD  biSize;    LONG   biWidth;    LONG   biHeight;    WORD   biPlanes;    WORD   biBitCount;    DWORD  biCompression;    DWORD  biSizeImage;    LONG   biXPelsPerMeter;    LONG   biYPelsPerMeter;    DWORD  biClrUsed;    DWORD  biClrImportant;} BITMAPINFOHEADER;typedef struct tagBITMAPFILEHEADER {   WORD    bfType;   DWORD   bfSize;   WORD    bfReserved1;   WORD    bfReserved2;   DWORD   bfOffBits; } BITMAPFILEHEADER, *PBITMAPFILEHEADER; #pragma pack()#endif // not WIN32GImage::GImage(){	m_pPixels = NULL;	m_nWidth = 0;	m_nHeight = 0;}GImage::~GImage(){	delete[] m_pPixels;}void GImage::SetSize(int nWidth, int nHeight){	if(nWidth == (int)m_nWidth && nHeight == (int)m_nHeight)		return;	delete(m_pPixels);	if(nWidth == 0 || nHeight == 0)		m_pPixels = NULL;	else	{		unsigned int nSize = nWidth * nHeight;		m_pPixels = new GColor[nSize];		memset(m_pPixels, '\0', nSize * sizeof(GColor));	}	m_nWidth = nWidth;	m_nHeight = nHeight;}void GImage::CopyImage(GImage* pSourceImage){	SetSize(pSourceImage->GetWidth(), pSourceImage->GetHeight());	memcpy(m_pPixels, pSourceImage->GetRGBQuads(), m_nWidth * m_nHeight * sizeof(GColor));}void GImage::CopyImage(GImage* pSourceImage, int nLeft, int nTop, int nRight, int nBottom){	int nWidth = nRight - nLeft + 1;	int nHeight = nBottom - nTop + 1;	SetSize(nWidth, nHeight);	int x, y;	GColor c;	for(y = 0; y < nHeight; y++)	{		for(x = 0; x < nWidth; x++)		{			c = pSourceImage->GetPixel(x + nLeft, y + nTop);			SetPixel(x, y, c);		}	}}void GImage::Clear(GColor color){	unsigned int nSize = m_nWidth * m_nHeight;	unsigned int nPos;	for(nPos = 0; nPos < nSize; nPos++)		m_pPixels[nPos] = color;}void GImage::SoftSetPixel(int nX, int nY, GColor color, double dOpacity){	GColor cOld = GetPixel(nX, nY);	GColor c = gRGB(		(unsigned char)((1 - dOpacity) * gRed(cOld) + dOpacity * gRed(color)),		(unsigned char)((1 - dOpacity) * gGreen(cOld) + dOpacity * gGreen(color)),		(unsigned char)((1 - dOpacity) * gBlue(cOld) + dOpacity * gBlue(color)));	SetPixel(nX, nY, c);}void GImage::SafeSetPixel(int nX, int nY, GColor color){	if(nX < 0 || nX >= (int)m_nWidth)		return;	if(nY < 0 || nY >= (int)m_nHeight)		return;	SetPixel(nX, nY, color);}GColor GImage::SafeGetPixel(int nX, int nY){	if(nX >= 0 && nX < (int)m_nWidth && nY >= 0 && nY < (int)m_nHeight)		return GetPixel(nX, nY);	else		return 0;}GColor GImage::InterpolatePixel(float dX, float dY){	int nX = (int)dX;	int nY = (int)dY;	float dXDif = dX - nX;	float dYDif = dY - nY;	GColor c1;	GColor c2;	c1 = SafeGetPixel(nX, nY);	c2 = SafeGetPixel(nX + 1, nY);	float dA1 = dXDif * (float)gAlpha(c2) + (1 - dXDif) * (float)gAlpha(c1);	float dR1 = dXDif * (float)gRed(c2) + (1 - dXDif) * (float)gRed(c1);	float dG1 = dXDif * (float)gGreen(c2) + (1 - dXDif) * (float)gGreen(c1);	float dB1 = dXDif * (float)gBlue(c2) + (1 - dXDif) * (float)gBlue(c1);	c1 = SafeGetPixel(nX, nY + 1);	c2 = SafeGetPixel(nX + 1, nY + 1);	float dA2 = dXDif * (float)gAlpha(c2) + (1 - dXDif) * (float)gAlpha(c1);	float dR2 = dXDif * (float)gRed(c2) + (1 - dXDif) * (float)gRed(c1);	float dG2 = dXDif * (float)gGreen(c2) + (1 - dXDif) * (float)gGreen(c1);	float dB2 = dXDif * (float)gBlue(c2) + (1 - dXDif) * (float)gBlue(c1);	return gARGB((int)(dYDif * dA2 + (1 - dYDif) * dA1),				(int)(dYDif * dR2 + (1 - dYDif) * dR1),				(int)(dYDif * dG2 + (1 - dYDif) * dG1),				(int)(dYDif * dB2 + (1 - dYDif) * dB1));}bool GImage::LoadFile(const char* szFilename){	int nLen = strlen(szFilename);	if(nLen < 4)		return false;	const char* szExt = szFilename + nLen - 4;	if(stricmp(szExt, ".png") == 0)		return LoadPNGFile(szFilename);	else if(stricmp(szExt, ".bmp") == 0)		return LoadBMPFile(szFilename);	else if(stricmp(szExt, ".ppm") == 0)		return LoadPPMFile(szFilename);	else if(stricmp(szExt, ".pgm") == 0)		return LoadPGMFile(szFilename);	else		return false;}bool GImage::LoadPPMFile(const char* szFilename){	GAssert(szFilename, "no filename");	FILE* pFile = fopen(szFilename, "rb");	if(!pFile)		return false;	char pBuff[2];	if(fread(pBuff, 2, 1, pFile) != 1)	{		fclose(pFile);		return false;	}	if(pBuff[0] != 'P' && pBuff[0] != 'p')	{		fclose(pFile);		return false;	}	bool bRet = false;	if(pBuff[1] == '3')		bRet = LoadPixMap(pFile, true, false);	else if(pBuff[1] == '6')		bRet = LoadPixMap(pFile, false, false);	fclose(pFile);	return bRet;}bool GImage::LoadPixMap(FILE* pFile, bool bTextData, bool bGrayScale){	GAssert(pFile, "no file");	int n;	// Read past any white space and skip comments	while(true)	{		n = fgetc(pFile);		if(n == '#')		{			while(true)			{				n = fgetc(pFile);				if(n == EOF)					return false;				if(n == '\n')					break;			}		}		if(n == EOF)			return false;		if(n > 32)			break;	}	// Read until the next white space to get width	char pBuff[16];	pBuff[0] = n;	int nPos = 1;	while(true)	{		n = fgetc(pFile);		if(n == EOF)			return false;		if(n <= 32)			break;		pBuff[nPos] = n;		nPos++;		if(nPos >= 16)			return false;	}	pBuff[nPos] = '\0';	int nWidth = atoi(pBuff);	if(nWidth < 1)		return false;	// Read past any white space and skip comments	while(true)	{		n = fgetc(pFile);		if(n == '#')		{			while(true)			{				n = fgetc(pFile);				if(n == EOF)					return false;				if(n == '\n')					break;			}		}		if(n == EOF)			return false;		if(n > 32)			break;	}	// Read until the next white space to get height	pBuff[0] = n;	nPos = 1;	while(true)	{		n = fgetc(pFile);		if(n == EOF)			return false;		if(n <= 32)			break;		pBuff[nPos] = n;		nPos++;		if(nPos >= 16)			return false;	}	pBuff[nPos] = '\0';	int nHeight = atoi(pBuff);	if(nHeight < 1)		return false;	// Read past any white space and skip comments	while(true)	{		n = fgetc(pFile);		if(n == '#')		{			while(true)			{				n = fgetc(pFile);				if(n == EOF)					return false;				if(n == '\n')					break;			}		}		if(n == EOF)			return false;		if(n > 32)			break;	}	// Read until the next white space to get range	pBuff[0] = n;	nPos = 1;	while(true)	{		n = fgetc(pFile);		if(n == EOF)			return false;		if(n <= 32)			break;		pBuff[nPos] = n;		nPos++;		if(nPos >= 16)			return false;	}	pBuff[nPos] = '\0';	int nRange = atoi(pBuff) + 1;	if(nRange < 2)		return false;	// Read the data	SetSize(nWidth, nHeight);	if(bTextData)	{		return false;	}	else	{		int x;		int y;		unsigned int nRed;		unsigned int nGreen;		unsigned int nBlue;		for(y = 0; y < nHeight; y++)		{			for(x = 0; x < nWidth; x++)			{				if(bGrayScale)				{					if(fread(pBuff, 1, 1, pFile) != 1)						return false;					nRed = (pBuff[0] << 8) / nRange;					nGreen = (pBuff[0] << 8) / nRange;					nBlue = (pBuff[0] << 8) / nRange;				}				else				{					if(fread(pBuff, 3, 1, pFile) != 1)						return false;					nRed = (pBuff[0] << 8) / nRange;					nGreen = (pBuff[1] << 8) / nRange;					nBlue = (pBuff[2] << 8) / nRange;				}				SetPixel(x, y, gRGB(nRed, nGreen, nBlue));			}		}	}	return true;}bool GImage::LoadPGMFile(const char* szFilename){	GAssert(szFilename, "no filename");	FILE* pFile = fopen(szFilename, "rb");	if(!pFile)		return false;	char pBuff[2];	if(fread(pBuff, 2, 1, pFile) != 1)	{		fclose(pFile);		return false;	}	if(pBuff[0] != 'P' && pBuff[0] != 'p')	{		fclose(pFile);		return false;	}	bool bRet = false;	if(pBuff[1] == '2')		bRet = LoadPixMap(pFile, true, true);	else if(pBuff[1] == '5')		bRet = LoadPixMap(pFile, false, true);	fclose(pFile);	return bRet;}bool GImage::SavePixMap(FILE* pFile, bool bTextData, bool bGrayScale){	// Write header junk	char szBuff[24];	itoa(m_nWidth, szBuff, 10);	fputs(szBuff, pFile);	fputs(" ", pFile);	itoa(m_nHeight, szBuff, 10);	fputs(szBuff, pFile);	fputs("\n255\n", pFile);	// Write pixel data	int x;	int y;	GColor col;	for(y = 0; y < m_nHeight; y++)	{		for(x = 0; x < m_nWidth; x++)		{			if(bGrayScale)			{				col = GetPixel(x, y);				unsigned char nGray = (77 * (int)gRed(col) + 150 * (int)gGreen(col) + 29 * (int)gBlue(col)) >> 8;				if(fwrite(&nGray, 1, 1, pFile) != 1)					return false;			}			else			{				col = GetPixel(x, y);				int n;				n = gRed(col);				if(fwrite(&n, 1, 1, pFile) != 1)					return false;				n = gGreen(col);				if(fwrite(&n, 1, 1, pFile) != 1)					return false;				n = gBlue(col);				if(fwrite(&n, 1, 1, pFile) != 1)					return false;			}		}	}	return true;}bool GImage::SavePPMFile(const char* szFilename){	FILE* pFile = fopen(szFilename, "wb");	if(!pFile)		return false;	if(fputs("P6\n", pFile) == EOF)		return false;	bool bRet = SavePixMap(pFile, false, false);	fclose(pFile);	return bRet;}bool GImage::SavePGMFile(const char* szFilename){	FILE* pFile = fopen(szFilename, "wb");	if(!pFile)		return false;	if(fputs("P5\n", pFile) == EOF)		return false;	bool bRet = SavePixMap(pFile, false, true);	fclose(pFile);	return bRet;}inline GColor ColorToGrayScale(GColor c){	int nGray = (77 * gRed(c) + 150 * gGreen(c) + 29 * gBlue(c)) >> 8;	return gRGB(nGray, nGray, nGray);}void GImage::ConvertToGrayScale(){	unsigned int nSize = m_nWidth * m_nHeight;	unsigned int nPos;	for(nPos = 0; nPos < nSize; nPos++)		m_pPixels[nPos] = ColorToGrayScale(m_pPixels[nPos]);}void GImage::CreateBrightnessHistogram(GImage* pOutImage){	// Create the histogram data	unsigned int pnHistData[256];	int n;	for(n = 0; n < 256; n++)		pnHistData[n] = 0;	unsigned int nSize = m_nWidth * m_nHeight;	unsigned int nPos;	unsigned int nGray;	unsigned int nMaxValue = 0;	for(nPos = 0; nPos < nSize; nPos++)	{		nGray = ColorToGrayScale(m_pPixels[nPos]);		pnHistData[nGray]++;		if(pnHistData[nGray] > nMaxValue)			nMaxValue = pnHistData[nGray];	}	// turn it into a picture	pOutImage->SetSize(256, 256);	pOutImage->Clear(gRGB(220, 220, 180));	int x;	int y;	for(x = 0; x < 256; x++)	{		int nHeight = pnHistData[x] * 256 / nMaxValue;		for(y = 0; y < nHeight; y++)			pOutImage->SetPixel(x, 255 - y, gRGB(y, 255 - y, 80));	}}void GImage::EqualizeColorSpread(){	// Create the histogram data	unsigned int pnHistData[256];	int n;	for(n = 0; n < 256; n++)		pnHistData[n] = 0;	unsigned int nSize = m_nWidth * m_nHeight;	unsigned int nPos;	unsigned int nGray;	unsigned int nMaxValue = 0;	for(nPos = 0; nPos < nSize; nPos++)	{		nGray = ColorToGrayScale(m_pPixels[nPos]);		pnHistData[nGray]++;		if(pnHistData[nGray] > nMaxValue)			nMaxValue = pnHistData[nGray];	}	// Turn it into cumulative histogram data	for(n = 1; n < 256; n++)		pnHistData[n] += pnHistData[n - 1];	int nFactor = pnHistData[255] >> 8;	// turn it into a picture	int x;	int y;	GColor col;	float fFactor;	for(y = 0; y < m_nHeight; y++)	{		for(x = 0; x < m_nWidth; x++)		{			col = GetPixel(x, y);			nGray = (77 * (int)gRed(col) + 150 * (int)gGreen(col) + 29 * (int)gBlue(col)) >> 8;			fFactor = ((float)pnHistData[nGray] / (float)nFactor) / nGray;						SetPixel(x, y, 				gRGB(				(char)MIN((int)((float)gRed(col) * fFactor), 255),				(char)MIN((int)((float)gGreen(col) * fFactor), 255),				(char)MIN((int)((float)gBlue(col) * fFactor), 255)					));		}	}}void GImage::LocallyEqualizeColorSpread(int nLocalSize, float fExtent){	if(nLocalSize % 2 != 0)		nLocalSize++;	GAssert(nLocalSize > 2, "Local size must be more than 2");		// Create histograms for all the local regions	int nHalfRegionSize = nLocalSize >> 1;	int nHorizRegions = (m_nWidth + nHalfRegionSize - 1) / nHalfRegionSize + 1;	int nVertRegions = (m_nHeight + nHalfRegionSize - 1) / nHalfRegionSize + 1;	int* pArrHistograms = new int[256 * nHorizRegions * nVertRegions];	memset(pArrHistograms, '\0', 256 * nHorizRegions * nVertRegions * sizeof(int));	int* pHist;	GAssert(pArrHistograms, "Failed to allocate memory");	int nHoriz, nVert, nDX, nDY, nX, nY, nGrayscale, n;	GColor col;	for(nVert = 0; nVert < nVertRegions; nVert++)	{		for(nHoriz = 0; nHoriz < nHorizRegions; nHoriz++)		{			// Make a histogram for the local region			pHist = pArrHistograms + 256 * (nHorizRegions * nVert + nHoriz);			for(nDY = 0; nDY < nLocalSize; nDY++)			{				nY = (nVert - 1) * nHalfRegionSize + nDY;				for(nDX = 0; nDX < nLocalSize; nDX++)				{					nX = (nHoriz - 1) * nHalfRegionSize + nDX;					if(nX >= 0 && nX < (int)m_nWidth && nY >= 0 && nY < (int)m_nHeight)					{						col = GetPixel(nX, nY);						nGrayscale = (77 * (int)gRed(col) + 150 * (int)gGreen(col) + 29 * (int)gBlue(col)) >> 8;						pHist[nGrayscale]++;					}				}			}						// Turn the histogram into cumulative histogram data			for(n = 1; n < 256; n++)				pHist[n] += pHist[n - 1];		}	}		// Equalize the colors	float fFactor1, fFactor2, fFactor3, fFactor4, fFactorTop, fFactorBottom, fFactorInterpolated;	float fInterp;	for(nY = 0; nY < (int)m_nHeight; nY++)	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -