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

📄 gimage.cpp

📁 一个非常有用的开源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		nVert = nY / nHalfRegionSize;		GAssert(nVert < nVertRegions, "Region out of range");		nDY = nY % nHalfRegionSize;		for(nX = 0; nX < (int)m_nWidth; nX++)		{			// Get the Pixel			nHoriz = nX / nHalfRegionSize;			GAssert(nHoriz < nHorizRegions, "Region out of range");			nDX = nX % nHalfRegionSize;			col = GetPixel(nX, nY);			nGrayscale = (77 * (int)gRed(col) + 150 * (int)gGreen(col) + 29 * (int)gBlue(col)) >> 8;						// Calculate equalization factor for quadrant 1			pHist = pArrHistograms + 256 * (nHorizRegions * nVert + nHoriz);			fFactor1 = ((float)pHist[nGrayscale] / (float)pHist[255]) * 255 / nGrayscale;						// Calculate equalization factor for quadrant 2			pHist = pArrHistograms + 256 * (nHorizRegions * nVert + (nHoriz + 1));			fFactor2 = ((float)pHist[nGrayscale] / (float)pHist[255]) * 255 / nGrayscale;						// Calculate equalization factor for quadrant 3			pHist = pArrHistograms + 256 * (nHorizRegions * (nVert + 1) + nHoriz);			fFactor3 = ((float)pHist[nGrayscale] / (float)pHist[255]) * 255 / nGrayscale;						// Calculate equalization factor for quadrant 4			pHist = pArrHistograms + 256 * (nHorizRegions * (nVert + 1) + (nHoriz + 1));			fFactor4 = ((float)pHist[nGrayscale] / (float)pHist[255]) * 255 / nGrayscale;						// Interpolate a factor from all 4 quadrants			fInterp = (float)nDX / (float)(nHalfRegionSize - 1);			fFactorTop = fInterp * fFactor2 + (1 - fInterp) * fFactor1;			fFactorBottom = fInterp * fFactor4 + (1 - fInterp) * fFactor3;			fInterp = (float)nDY / (float)(nHalfRegionSize - 1);			fFactorInterpolated = (fInterp * fFactorBottom + (1 - fInterp) * fFactorTop) * fExtent + 1 - fExtent;			// Set the Pixel			SetPixel(nX, nY,				gRGB(					(char)MAX(0, MIN((int)((float)gRed(col) * fFactorInterpolated), 255)),					(char)MAX(0, MIN((int)((float)gGreen(col) * fFactorInterpolated), 255)),					(char)MAX(0, MIN((int)((float)gBlue(col) * fFactorInterpolated), 255))					));		}	}}void GImage::SafeDrawLine(int nX1, int nY1, int nX2, int nY2, GColor color){	/*	// Note: This uses the DDA line drawing algorythm (which is slower than the	// Bresenham algorythm, but I had to do it this way for a class I'm taking.)	int nSteps = MAX(ABS(nX2 - nX1), ABS(nY2 - nY1));	double dXStep = (double)(nX2 - nX1) / (double)nSteps;	double dYStep = (double)(nY2 - nY1) / (double)nSteps;	int n;	double dX = nX1 + .5;	double dY = nY1 + .5;	SafeSetPixel((int)dX, (int)dY, color);	for(n = 0; n < nSteps; n++)	{		dX += dXStep;		dY += dYStep;		SafeSetPixel((int)dX, (int)dY, color);	}	*/	// Check nX1	if(nX1 < 0)	{		if(nX2 < 0)			return;		nY1 = (nY1 - nY2) * nX2 / (nX2 - nX1) + nY2;		nX1 = 0;	}	if(nX1 >= m_nWidth)	{		if(nX2 >= m_nWidth)			return;		nY1 = (nY1 - nY2) * (m_nWidth - 1 - nX2) / (nX2 - nX1) + nY2;		nX1 = m_nWidth - 1;	}	// Check nY1	if(nY1 < 0)	{		if(nY2 < 0)			return;		nX1 = (nX1 - nX2) * nY2 / (nY2 - nY1) + nX2;		nY1 = 0;	}	if(nY1 >= m_nHeight)	{		if(nY2 >= m_nHeight)			return;		nX1 = (nX1 - nX2) * (m_nHeight - 1 - nY2) / (nY2 - nY1) + nX2;		nY1 = m_nHeight - 1;	}	// Check nX2	if(nX2 < 0)	{		if(nX1 < 0)			return;		nY2 = (nY2 - nY1) * nX1 / (nX1 - nX2) + nY1;		nX2 = 0;	}	if(nX2 >= m_nWidth)	{		if(nX1 >= m_nWidth)			return;		nY2 = (nY2 - nY1) * (m_nWidth - 1 - nX1) / (nX2 - nX1) + nY1;		nX2 = m_nWidth - 1;	}	// Check nY2	if(nY2 < 0)	{		if(nY1 < 0)			return;		nX2 = (nX2 - nX1) * nY1 / (nY1 - nY2) + nX1;		nY2 = 0;	}	if(nY2 >= m_nHeight)	{		if(nY1 >= m_nHeight)			return;		nX2 = (nX2 - nX1) * (m_nHeight - 1 - nY1) / (nY1 - nY2) + nX1;		nY2 = m_nHeight - 1;	}	DrawLine(nX1, nY1, nX2, nY2, color);}// Note: This uses the Bresenham line drawing algorythmvoid GImage::DrawLine(int nX1, int nY1, int nX2, int nY2, GColor color){	int n;	int nXDif = ABS(nX2 - nX1);	int nYDif = ABS(nY2 - nY1);	int nOverflow;	int m;	if(nXDif > nYDif)	{		if(nX2 < nX1)		{			n = nX2;			nX2 = nX1;			nX1 = n;			n = nY2;			nY2 = nY1;			nY1 = n;		}		nOverflow = nXDif >> 1;		m = nY1;		if(nY1 < nY2)		{			for(n = nX1; n <= nX2; n++)			{				SetPixel(n, m, color);				nOverflow += nYDif;				if(nOverflow >= nXDif)				{					nOverflow -= nXDif;					m++;				}			}		}		else		{			for(n = nX1; n <= nX2; n++)			{				SetPixel(n, m, color);				nOverflow += nYDif;				if(nOverflow >= nXDif)				{					nOverflow -= nXDif;					m--;				}			}		}	}	else	{		if(nY2 < nY1)		{			n = nX2;			nX2 = nX1;			nX1 = n;			n = nY2;			nY2 = nY1;			nY1 = n;		}		nOverflow = nYDif >> 1;		m = nX1;		if(nX1 < nX2)		{			for(n = nY1; n <= nY2; n++)			{				SetPixel(m, n, color);				nOverflow += nXDif;				if(nOverflow >= nYDif)				{					nOverflow -= nYDif;					m++;				}			}		}		else		{			for(n = nY1; n <= nY2; n++)			{				SetPixel(m, n, color);				nOverflow += nXDif;				if(nOverflow >= nYDif)				{					nOverflow -= nYDif;					m--;				}			}		}	}}void GImage::DrawLineAntiAlias(int nX1, int nY1, int nX2, int nY2, GColor color){	int n;	int m;	int nXDif = ABS(nX2 - nX1);	int nYDif = ABS(nY2 - nY1);	int nOverflow;	GColor col;	double d;	if(nXDif > nYDif)	{		if(nX2 < nX1)		{			n = nX2;			nX2 = nX1;			nX1 = n;			n = nY2;			nY2 = nY1;			nY1 = n;		}		nOverflow = 0;		m = nY1;		if(nY1 < nY2)		{			for(n = nX1; n <= nX2; n++)			{				d = (double)nOverflow / nXDif;				col = GetPixel(n, m);				SetPixel(n, m, 					gRGB((unsigned char)(d * gRed(col) + (1 - d) * gRed(color)), (unsigned char)(d * gGreen(col) + (1 - d) * gGreen(color)), (unsigned char)(d * gBlue(col) + (1 - d) * gBlue(color))));				col = GetPixel(n, m + 1);				SetPixel(n, m + 1, 					gRGB((unsigned char)((1 - d) * gRed(col) + d * gRed(color)), (unsigned char)((1 - d) * gGreen(col) + d * gGreen(color)), (unsigned char)((1 - d) * gBlue(col) + d * gBlue(color))));				nOverflow += nYDif;				if(nOverflow >= nXDif)				{					nOverflow -= nXDif;					m++;				}			}		}		else		{			for(n = nX1; n <= nX2; n++)			{				d = (double)nOverflow / nXDif;				col = GetPixel(n, m);				SetPixel(n, m, 					gRGB((unsigned char)(d * gRed(col) + (1 - d) * gRed(color)), (unsigned char)(d * gGreen(col) + (1 - d) * gGreen(color)), (unsigned char)(d * gBlue(col) + (1 - d) * gBlue(color))));				col = GetPixel(n, m - 1);				SetPixel(n, m - 1, 					gRGB((unsigned char)((1 - d) * gRed(col) + d * gRed(color)), (unsigned char)((1 - d) * gGreen(col) + d * gGreen(color)), (unsigned char)((1 - d) * gBlue(col) + d * gBlue(color))));				nOverflow += nYDif;				if(nOverflow >= nXDif)				{					nOverflow -= nXDif;					m--;				}			}		}	}	else	{		if(nY2 < nY1)		{			n = nX2;			nX2 = nX1;			nX1 = n;			n = nY2;			nY2 = nY1;			nY1 = n;		}		nOverflow = 0;		m = nX1;		if(nX1 < nX2)		{			for(n = nY1; n <= nY2; n++)			{				d = (double)nOverflow / nYDif;				col = GetPixel(m, n);				SetPixel(m, n, 					gRGB((unsigned char)(d * gRed(col) + (1 - d) * gRed(color)), (unsigned char)(d * gGreen(col) + (1 - d) * gGreen(color)), (unsigned char)(d * gBlue(col) + (1 - d) * gBlue(color))));				col = GetPixel(m + 1, n);				SetPixel(m + 1, n, 					gRGB((unsigned char)((1 - d) * gRed(col) + d * gRed(color)), (unsigned char)((1 - d) * gGreen(col) + d * gGreen(color)), (unsigned char)((1 - d) * gBlue(col) + d * gBlue(color))));				nOverflow += nXDif;				if(nOverflow >= nYDif)				{					nOverflow -= nYDif;					m++;				}			}		}		else		{			for(n = nY1; n <= nY2; n++)			{				d = (double)nOverflow / nYDif;				col = GetPixel(m, n);				SetPixel(m, n, 					gRGB((unsigned char)(d * gRed(col) + (1 - d) * gRed(color)), (unsigned char)(d * gGreen(col) + (1 - d) * gGreen(color)), (unsigned char)(d * gBlue(col) + (1 - d) * gBlue(color))));				col = GetPixel(m - 1, n);				SetPixel(m - 1, n, 					gRGB((unsigned char)((1 - d) * gRed(col) + d * gRed(color)), (unsigned char)((1 - d) * gGreen(col) + d * gGreen(color)), (unsigned char)((1 - d) * gBlue(col) + d * gBlue(color))));				nOverflow += nXDif;				if(nOverflow >= nYDif)				{					nOverflow -= nYDif;					m--;				}			}		}	}}void GImage::FloodFillRecurser(int nX, int nY, unsigned char nSrcR, unsigned char nSrcG, unsigned char nSrcB, unsigned char nDstR, unsigned char nDstG, unsigned char nDstB, int nTolerance){	GColor col;	int nDif;	while(true)	{		col = GetPixel(nX - 1, nY);		nDif = ABS((int)gRed(col) - nSrcR) + ABS((int)gGreen(col) - nSrcG) + ABS((int)gBlue(col) - nSrcB);		if(nDif > nTolerance || nX < 1)			break;		nX--;	}	GBitTable btUp(m_nWidth);	GBitTable btDn(m_nWidth);	while(true)	{		SetPixel(nX, nY, gRGB(nDstR, nDstG, nDstB));		if(nY > 0)		{			col = GetPixel(nX, nY - 1);			if(gRed(col) != nDstR || gGreen(col) != nDstG || gBlue(col) != nDstB)			{				nDif = ABS((int)gRed(col) - nSrcR) + ABS((int)gGreen(col) - nSrcG) + ABS((int)gBlue(col) - nSrcB);				if(nDif <= nTolerance)					btUp.SetBit(nX, true);			}		}				if(nY < (int)m_nHeight - 1)		{			col = GetPixel(nX, nY + 1);			if(gRed(col) != nDstR || gGreen(col) != nDstG || gBlue(col) != nDstB)			{				nDif = ABS((int)gRed(col) - nSrcR) + ABS((int)gGreen(col) - nSrcG) + ABS((int)gBlue(col) - nSrcB);				if(nDif <= nTolerance)					btDn.SetBit(nX, true);			}		}		nX++;		if(nX >= (int)m_nWidth)			break;		col = GetPixel(nX, nY);		nDif = ABS((int)gRed(col) - nSrcR) + ABS((int)gGreen(col) - nSrcG) + ABS((int)gBlue(col) - nSrcB);		if(nDif > nTolerance)			break;	}	bool bPrev = false;	for(nX = 0; nX < (int)m_nWidth; nX++)	{		if(btUp.GetBit(nX))		{			if(!bPrev)			{				col = GetPixel(nX, nY - 1);				if(gRed(col) != nDstR || gGreen(col) != nDstG || gBlue(col) != nDstB)					FloodFillRecurser(nX, nY - 1, nSrcR, nSrcG, nSrcB, nDstR, nDstG, nDstB, nTolerance);			}			bPrev = true;		}		else			bPrev = false;	}	bPrev = false;	for(nX = 0; nX < (int)m_nWidth; nX++)	{		if(btDn.GetBit(nX))		{			if(!bPrev)			{				col = GetPixel(nX, nY + 1);				if(gRed(col) != nDstR || gGreen(col) != nDstG || gBlue(col) != nDstB)					FloodFillRecurser(nX, nY + 1, nSrcR, nSrcG, nSrcB, nDstR, nDstG, nDstB, nTolerance);			}			bPrev = true;		}		else			bPrev = false;	}}void GImage::FloodFill(int nX, int nY, GColor color, int nTolerance){	GColor col = GetPixel(nX, nY);	FloodFillRecurser(nX, nY, gRed(col), gGreen(col), gBlue(col), gRed(color), gGreen(color), gBlue(color), nTolerance);}void GImage::BoundaryFill(int nX, int nY, unsigned char nBoundaryR, unsigned char nBoundaryG, unsigned char nBoundaryB, unsigned char nFillR, unsigned char nFillG, unsigned char nFillB, int nTolerance){	int nDif;	GColor col = GetPixel(nX, nY);	nDif = ABS((int)gRed(col) - nBoundaryR) + ABS((int)gGreen(col) - nBoundaryG) + ABS((int)gBlue(col) - nBoundaryB);	if(nDif <= nTolerance)		return;	while(true)	{		col = GetPixel(nX - 1, nY);		nDif = ABS((int)gRed(col) - nBoundaryR) + ABS((int)gGreen(col) - nBoundaryG) + ABS((int)gBlue(col) - nBoundaryB);		if(nDif <= nTolerance || nX < 1)			break;		nX--;	}	GBitTable btUp(m_nWidth);	GBitTable btDn(m_nWidth);	while(true)	{		SetPixel(nX, nY, gRGB(nFillR, nFillG, nFillB));		if(nY > 0)		{			col = GetPixel(nX, nY - 1);			if(gRed(col) != nFillR || gGreen(col) != nFillG || gBlue(col) != nFillB)			{				nDif = ABS((int)gRed(col) - nBoundaryR) + ABS((int)gGreen(col) - nBoundaryG) + ABS((int)gBlue(col) - nBoundaryB);				if(nDif > nTolerance)					btUp.SetBit(nX, true);			}		}				if(nY < (int)m_nHeight - 1)		{			col = GetPixel(nX, nY + 1);			if(gRed(col) != nFillR || gGreen(col) != nFillG || gBlue(col) != nFillB)			{				nDif = ABS((int)gRed(col) - nBoundaryR) + ABS((int)gGreen(col) - nBoundaryG) + ABS((int)gBlue(col) - nBoundaryB);				if(nDif > nTolerance)					btDn.SetBit(nX, true);			}		}		nX++;		if(nX >= (int)m_nWidth)			break;		col = GetPixel(nX, nY);		nDif = ABS((int)gRed(col) - nBoundaryR) + ABS((int)gGreen(col) - nBoundaryG) + ABS((int)gBlue(col) - nBoundaryB);		if(nDif <= nTolerance)			break;	}	bool bPrev = false;	for(nX = 0; nX < (int)m_nWidth; nX++)	{		if(btUp.GetBit(nX))		{			if(!bPrev)			{				col = GetPixel(nX, nY - 1);				if(gRed(col) != nFillR || gGreen(col) != nFillG || gBlue(col) != nFillB)					BoundaryFill(nX, nY - 1, nBoundaryR, nBoundaryG, nBoundaryB, nFillR, nFillG, nFillB, nTolerance);			}			bPrev = true;		}		else			bPrev = false;	}	bPrev = false;	for(nX = 0; nX < (int)m_nWidth; nX++)	{		if(btDn.GetBit(nX))		{			if(!bPrev)			{				col = GetPixel(nX, nY + 1);				if(gRed(col) != nFillR || gGreen(col) != nFillG || gBlue(col) != nFillB)					BoundaryFill(nX, nY + 1, nBoundaryR, nBoundaryG, nBoundaryB, nFillR, nFillG, nFillB, nTolerance);			}			bPrev = true;		}		else			bPrev = false;	}}void GImage::DrawPolygon(int nPoints, int* pnPtArray, GColor color){	if(nPoints < 3)		return;	float* pnPointArray = new float[nPoints << 1];	int n;	for(n = 0; n < nPoints << 1; n++)		pnPointArray[n] = ((float)pnPtArray[n]) + .1f;	for(n = 0; n < nPoints; n++)	{		int n2 = n + 1;		if(n2 >= nPoints)			n2 = 0;		SafeDrawLine(pnPtArray[n << 1], pnPtArray[(n << 1) + 1], pnPtArray[n2 << 1], pnPtArray[(n2 << 1) + 1], color);	}	// Find Max and Min values	int nXMin = (int)pnPointArray[0];	int nXMax = (int)pnPointArray[0];	int nYMin = (int)pnPointArray[1];	int nYMax = (int)pnPointArray[1];	int nPos = 2;	for(n = 1; n < nPoints; n++)	{		if(pnPointArray[nPos] < nXMin)			nXMin = (int)pnPointArray[nPos];		if(pnPointArray[nPos] + 1 > nXMax)			nXMax = (int)pnPointArray[nPos] + 1;		nPos++;		if(pnPointArray[nPos] < nYMin)			nYMin = (int)pnPointArray[nPos];		if(pnPointArray[nPos] + 1 > nYMax)			nYMax = (int)pnPointArray[nPos] + 1;		nPos++;	}	int nX, nY;	int* pArrPts = new int[m_nWidth];	for(nY = nYMin; nY <= nYMax; nY++)	{		memset(pArrPts, '\0', sizeof(int) * m_nWidth);				// Calculate Intercepts		for(n = 0; n < nPoints; n++)		{			int n2 = n + 1;			if(n2 >= nPoints)				n2 = 0;			float nX1 = pnPointArray[n << 1];			float nY1 = pnPointArray[(n << 1) + 1];			float nX2 = pnPointArray[n2 << 1];			float nY2 = pnPointArray[(n2 << 1) + 1];			if(nY < nY1 && nY < nY2)				continue;			if(nY > nY1 && nY > nY2)				continue;			nX = (int)(nX1 + (nY - nY1) * (nX2 - nX1) / (nY2 - nY1));			if(nX < 0)				nX = 0;			if(nX >= (int)m_nWidth)				nX = (int)m_nWidth - 1;			pArrPts[nX]++;		}		// Draw the Scan Line		bool bOn = false;		for(nX = nXMin; nX <= nXMax; nX++)		{			if(bOn || pArrPts[nX])				SafeSetPixel(nX, nY, color);			if(pArrPts[nX] & 1)				bOn = !bOn;		}	}	delete(pArrPts);}void GImage::DrawCircle(int nX, int nY, float fRadius, GColor color){	int radiusSquared = (int)(fRadius * fRadius + (float).5);	int x = 0;	int y = (int)fRadius;	while(y >= x)	{		// Draw the eight symmetric pixels		SafeSetPixel(nX + x, nY - y, color);		SafeSetPixel(nX - x, nY - y, color);		SafeSetPixel(nX + x, nY + y, color);		SafeSetPixel(nX - x, nY + y, color);		SafeSetPixel(nX + y, nY - x, color);		SafeSetPixel(nX - y, nY - x, color);		SafeSetPixel(nX + y, nY + x, color);		SafeSetPixel(nX - y, nY + x, color);		// Compute the next position		if(x * x + y * y > radiusSquared)			y--;		x++;	}	/*	double dAngle;	double dStep = .9 / dRadius;	if(dStep == 0)		return;	double dSin;	double dCos;	for(dAngle = 0; dAngle < 0.79; dAngle += dStep)	{		dSin = sin(dAngle);		dCos = cos(dAngle);

⌨️ 快捷键说明

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