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

📄 pic.cpp

📁 一个国人自己实现图像库的程序(有参考价值)
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			delete[] prgb ;
	}
}
//===================================================================
void  FCDib::__ConvertToTrueColor (int iColor)
{
	if ((this->GetHandle() == NULL) || (this->ColorBits () == iColor))
		return ;

	// 保存原始数据
	FCDib		OldPic (* (FCDib *) this) ;
	if (this->Create (OldPic.Width(), OldPic.Height(), iColor))
	{
		// 获取调色板
		RGBQUAD		* prgb = NULL ;
		if (OldPic.ColorBits() <= 8)
		{
			prgb = new RGBQUAD [1 << OldPic.ColorBits()] ;
			OldPic.GetColorTable (0, 1 << OldPic.ColorBits(), prgb) ;
		}

		// 颜色转换
		int			nNewSpan = this->ColorBits() / 8, // 3 or 4
					nOldSpan = OldPic.ColorBits() / 8, x, y ;
		BYTE		* pNew, * pOld ;
		for (y = 0 ; y < (int)this->Height() ; y++)
		{
			pNew = this->GetBits (y) ;
			pOld = OldPic.GetBits (y) ;
			switch (OldPic.ColorBits())
			{
				case 1 :
				case 4 : // 1,4 ==> 24,32
					for (x = 0 ; x < (int)this->Width() ; x++)
						this->SetPixelColor (x, y, prgb[(BYTE)OldPic.GetPixelData (x, y)]) ;
					break ;
				case 8 : // 8 ==> 24,32
					for (x = 0 ; x < (int)this->Width() ; x++, pNew += nNewSpan)
						CopyMemory (pNew, &prgb[pOld[x]], nNewSpan) ;
					break ;
				case 16 : // 16 ==> 24,32
					for (x = 0 ; x < (int)this->Width() ; x++, pNew += nNewSpan, pOld +=2)
						CopyMemory (pNew, &OldPic.ParsePixelData (*(WORD *)pOld), 3) ;
					break ;
				case 24 :
				case 32 : // 24,32 ==> 32,24
					for (x = 0 ; x < (int)this->Width() ; x++, pNew += nNewSpan, pOld += nOldSpan)
						CopyMemory (pNew, pOld, 3) ;
					break ;
			}
		}
		if (prgb != NULL)
			delete[] prgb ;
	}
}
//===================================================================
void  FCDib::fooRGBtoHLS (RGBTRIPLE rgb, double * H, double * L, double * S)
{
	double		delta ;
	double		r = (double) rgb.rgbtRed / 255 ;
	double		g = (double) rgb.rgbtGreen / 255 ;
	double		b = (double) rgb.rgbtBlue / 255 ;
	double		cmax = max (r, max (g, b)) ;
	double		cmin = min (r, min (g, b)) ;
	*L = (cmax+cmin) / 2.0 ;
	if (cmax == cmin)
	{
		*S = 0 ;
		*H = 0 ;
	}
	else
	{
		if (*L < 0.5) 
			*S = (cmax-cmin) / (cmax+cmin) ;
		else
			*S = (cmax-cmin) / (2.0-cmax-cmin) ;
		delta = cmax - cmin ;
		if (r == cmax)
			*H = (g-b) / delta ;
		else
			if (g == cmax)
				*H = 2.0 + (b-r) / delta ;
			else
				*H = 4.0 + (r-g) / delta ;
		*H /= 6.0 ;
		if (*H < 0.0)
			*H += 1 ;
	}
}
//===================================================================
double  FCDib::__fooHuetoRGB (double m1, double m2, double h)
{
	if (h < 0)
		h += 1.0 ;
	if (h > 1)
		h -= 1.0 ;
	if (6.0*h < 1)
		return (m1+(m2-m1)*h*6.0) ;
	if (2.0*h < 1)
		return m2 ;
	if (3.0*h < 2.0)
		return (m1+(m2-m1)*((2.0/3.0)-h)*6.0) ;
	return m1 ;
}
RGBTRIPLE  FCDib::fooHLStoRGB (const double& H, const double& L, const double& S)
{
	double		r, g, b ;
	double		m1, m2 ;

	if (S == 0)
		r = g = b = L ;
	else 
	{
		if (L <= 0.5)
			m2 = L * (1.0+S) ;
		else
			m2 = L + S - L*S ;
		m1 = 2.0*L - m2 ;
		r = FCDib::__fooHuetoRGB (m1, m2, H+1.0/3.0) ;
		g = FCDib::__fooHuetoRGB (m1, m2, H) ;
		b = FCDib::__fooHuetoRGB (m1, m2, H-1.0/3.0) ;
	}
	RGBTRIPLE		retRGB ;
	retRGB.rgbtRed = max (min ((int)(r*255), 0xFF), 0) ;
	retRGB.rgbtGreen = max (min ((int)(g*255), 0xFF), 0) ;
	retRGB.rgbtBlue = max (min ((int)(b*255), 0xFF), 0) ;
	return retRGB ;
}
//===================================================================
BOOL  FCDib::CopyToClipboard (const RECT * rect)
{
	BOOL	bRet = FALSE ;
	if (this->GetHandle () != NULL)
		if (rect == NULL)
		{
			if (::OpenClipboard (NULL))
			{
				HBITMAP		ddb = this->GetDDB_Handle () ;
				if (::EmptyClipboard () && (ddb != NULL))
					bRet = (::SetClipboardData (CF_BITMAP, ddb) != NULL) ;
				::CloseClipboard () ;
				::DeleteObject (ddb) ;
			}
		}
		else
		{
			FCDib	block ;
			if (this->GetSubBlock (&block, *rect))
				return block.CopyToClipboard (NULL) ;
		}
	return bRet ;
}
BOOL  FCDib::PasteFromClipboard (const RECT * rect)
{
	BOOL	bRet = FALSE ;
	if (this->IsPasteAvailable ())
		if (::OpenClipboard (NULL))
		{
			if (rect == NULL)
				if (IsClipboardFormatAvailable (CF_BITMAP))
					bRet = this->AttachDDB ((HBITMAP) ::GetClipboardData (CF_BITMAP), 32) ;
				else
				{
					BITMAPINFOHEADER	 * bmif = (BITMAPINFOHEADER *)::GetClipboardData (CF_DIB) ;
					bRet = this->Create (bmif->biWidth, bmif->biHeight, bmif->biBitCount) ;
					CopyMemory (this->GetMemStart(), ++bmif, this->GetPitch()*this->Height()) ;
				}
			else
			{
				FCDib	block ;
				if (IsClipboardFormatAvailable (CF_BITMAP))
				{
					bRet = block.AttachDDB ((HBITMAP) ::GetClipboardData (CF_BITMAP), this->ColorBits ()) ;
					bRet |= this->CoverBlock (block, rect->left, rect->top) ;
				}
				else
				{
					BITMAPINFOHEADER	 * bmif = (BITMAPINFOHEADER *)::GetClipboardData (CF_DIB) ;
					bRet = block.Create (bmif->biWidth, bmif->biHeight, bmif->biBitCount) ;
					CopyMemory (block.GetMemStart(), ++bmif, this->GetPitch()*this->Height()) ;
					bRet |= this->CoverBlock (block, rect->left, rect->top) ;
				}
			}
			::CloseClipboard() ;
		}
	return bRet ;
}
BOOL  FCDib::IsPasteAvailable () {
	return (IsClipboardFormatAvailable (CF_BITMAP) || IsClipboardFormatAvailable(CF_DIB)) ;
}
//===================================================================
void  FCDib::GetRGBChannel (FCDib * red, FCDib * green, FCDib * blue, FCDib * alpha)
{
	if (this->ColorBits() < 24)
		return ;

	if (red != NULL)	red->Create (this->Width(), this->Height(), 8) ;
	if (green != NULL)	green->Create (this->Width(), this->Height(), 8) ;
	if (blue != NULL)	blue->Create (this->Width(), this->Height(), 8) ;
	if ((alpha != NULL) && (this->ColorBits() == 32))
		alpha->Create (this->Width(), this->Height(), 8) ;

	int		nSpan = this->ColorBits() / 8 ; // 3 or 4
	for (DWORD y=0 ; y < this->Height () ; y++)
	{
		BYTE	* pRed = (red == NULL) ? NULL : red->GetBits (y),
				* pGreen = (green == NULL) ? NULL : green->GetBits (y),
				* pBlue = (blue == NULL) ? NULL : blue->GetBits (y),
				* pAlpha = NULL,
				* pSource = this->GetBits (y) ;
		if ((alpha != NULL) && (this->ColorBits() == 32))
			pAlpha = alpha->GetBits (y) ;

		for (DWORD x=0 ; x < this->Width () ; x++, pSource += nSpan)
		{
			if (blue != NULL)
				pBlue[x] = pSource[0] ;
			if (green != NULL)
				pGreen[x] = pSource[1] ;
			if (red != NULL)
				pRed[x] = pSource[2] ;
			if (pAlpha != NULL)
				pAlpha[x] = pSource[3] ;
		}
	}
}
//===================================================================
void  FCDib::CombineChannel (FCDib * red, FCDib * green, FCDib * blue, FCDib * alpha)
{
	if ((red == NULL) && (green == NULL) && (blue == NULL) && (alpha == NULL))
		return ;

	int		nWidth, nHeight ;
	if (red != NULL) { nWidth = red->Width() ; nHeight = red->Height() ; }
	if (green != NULL) { nWidth = green->Width() ; nHeight = green->Height() ; }
	if (blue != NULL) { nWidth = blue->Width() ; nHeight = blue->Height() ; }
	if (alpha != NULL) { nWidth = alpha->Width() ; nHeight = alpha->Height() ; }

	if (!this->Create (nWidth, nHeight, (alpha == NULL) ? 24 : 32))
		return ;

	int		nSpan = this->ColorBits() / 8 ; // 3 or 4
	for (DWORD y=0 ; y < this->Height () ; y++)
	{
		BYTE	* pRed = (red == NULL) ? NULL : red->GetBits (y),
				* pGreen = (green == NULL) ? NULL : green->GetBits (y),
				* pBlue = (blue == NULL) ? NULL : blue->GetBits (y),
				* pAlpha = (alpha == NULL) ? NULL : alpha->GetBits (y),
				* pDest = this->GetBits (y) ;
		for (DWORD x=0 ; x < this->Width () ; x++, pDest += nSpan)
		{
			if (blue != NULL)
				pDest[0] = pBlue[x] ;
			if (green != NULL)
				pDest[1] = pGreen[x] ;
			if (red != NULL)
				pDest[2] = pRed[x] ;
			if (alpha != NULL)
				pDest[3] = pAlpha[x] ;
		}
	}
}
//===================================================================
void  FCDib::AppendAlphaChannel (const FCDib & alpha)
{
	if ((this->ColorBits() == 32) && (alpha.ColorBits () == 8))
		if ((this->Width() == alpha.Width()) && (this->Height() == alpha.Height()))
		{
			for (DWORD y=0 ; y < this->Height () ; y++)
			{
				BYTE		* pAlpha = alpha.GetBits (y) ;
				RGBQUAD		* pDest = (RGBQUAD *) this->GetBits (y) ;
				for (DWORD x=0 ; x < this->Width () ; x++)
					pDest[x].rgbReserved = pAlpha[x] ;
			}
		}
}
//===================================================================
void  FCDib::InvertAlphaChannel ()
{
	if (this->ColorBits() == 32)
	{
		DWORD		nNum = this->Width() * this->Height() ;
		RGBQUAD		* pPixel = (RGBQUAD *)this->GetMemStart () ;
		for (DWORD i=0 ; i < nNum ; i++, pPixel++)
			pPixel->rgbReserved = ~pPixel->rgbReserved ;
	}
}
//===================================================================
bool  FCDib::IsGrayPalette () const
{
	bool	bRet = false ;
	if ((this->GetHandle () != NULL) && (this->ColorBits() <= 8))
	{
		int			nNum = 1 << this->ColorBits () ;
		RGBQUAD		* pal = new RGBQUAD[nNum] ;
		this->GetColorTable (0, nNum, pal) ;
		bRet = true ;
		for (int i=0 ; (i < nNum) && bRet ; i++)
			if ((pal[i].rgbBlue == pal[i].rgbGreen) && (pal[i].rgbBlue == pal[i].rgbRed))
				continue ;
			else
				bRet = false ;
		delete[] pal ;
	}
	return bRet ;
}
//===================================================================
BOOL  FCDib::GetSubBlock (FCDib * SubDib, const RECT & rcBlock) const
{
	RECT	now = {0, 0, this->Width(), this->Height()},
			rcDest ;
	if ((::IntersectRect (&rcDest, &now, &rcBlock) == 0) || (SubDib == NULL) || (SubDib == this)
		|| (this->ColorBits () < 8))
		return FALSE ; // 没有相交区域

	int		iRectW = rcDest.right - rcDest.left,
			iRectH = rcDest.bottom - rcDest.top ;
	if (!SubDib->Create (iRectW, iRectH, this->ColorBits()))
		return FALSE ;

	// 区域象素由上至下Copy
	DWORD	dwLength = iRectW * this->ColorBits() / 8 ;
	DWORD	dwPitch = this->GetPitch () ;
	BYTE	* pSrc = this->GetBits (rcDest.left, rcDest.top) ;
	for (int i = 0 ; i < iRectH ; i++, pSrc -= dwPitch)
		CopyMemory (SubDib->GetBits (i), pSrc, dwLength) ;

	// 复制调色板
	if (this->ColorBits() <= 8)
	{
		int			nNum = 1 << this->ColorBits() ;
		RGBQUAD		* pal = new RGBQUAD[nNum] ;
		this->GetColorTable (0, nNum, pal) ;
		SubDib->SetColorTable (0, nNum, pal) ;
		delete[] pal ;
	}
	return TRUE ;
}
//===================================================================
BOOL  FCDib::CoverBlock (const FCDib & Dib, int x, int y)
{
	RECT	now = {0, 0, Width(), Height()} ,
			sub = {x, y, x+Dib.Width(), y+Dib.Height()} ,
			rcDest ;
	if ((::IntersectRect (&rcDest, &now, &sub) == 0) || (this->ColorBits() != Dib.ColorBits())
		|| (this->ColorBits() < 8))
		return FALSE ; // 没有相交区域

	int		iRectW = rcDest.right - rcDest.left,
			iRectH = rcDest.bottom - rcDest.top ;
	DWORD	dwSubPitch = iRectW * Dib.ColorBits() / 8 ;
	DWORD	dwPitch = this->GetPitch() ;
	BYTE	* pDest = this->GetBits (x, y) ;
	for (int i = 0 ; i < iRectH ; i++, pDest -= dwPitch) // 由上至下Copy
		CopyMemory (pDest, Dib.GetBits (i), dwSubPitch) ;
	return TRUE ;
}
//===================================================================
void  FCDib::RegionFill (RGBQUAD rgb, RECT * rect)
{
	if (this->ColorBits() >= 16)
		if (rect == NULL)
		{
			if (this->ColorBits () == 16)
				* (WORD *) &rgb = FCDib::fooCombine16Bit_555 (&rgb) ;
			int		nSpan = this->ColorBits() / 8 ; // 2 or 3 or 4
			for (int y=0 ; y < (int)this->Height() ; y++)
			{
				BYTE	* pPixel = this->GetBits (y) ;
				for (int x=0 ; x < (int)this->Width() ; x++, pPixel += nSpan)
					CopyMemory (pPixel, &rgb, nSpan) ;
			}
		}
		else
		{
			FCDib		block ;
			this->GetSubBlock (&block, *rect) ;
			block.RegionFill (rgb, NULL) ;
			this->CoverBlock (block, rect->left, rect->top) ;
		}
}
//===================================================================
void  FCDib::LogicalOperate (const FCDib & Dib, DWORD dwRop, int x, int y)
{
	RECT	dib1 = {0, 0, Width(), Height()},
			dib2 = {x, y, x + Dib.Width(), y + Dib.Height()},
			rcDest ;
	if ((::IntersectRect (&rcDest, &dib1, &dib2) != 0) && (Dib.ColorBits() >= 24) && (this->ColorBits() >= 24))
	{
		int			nNewSpan = this->ColorBits() / 8,
					nOldSpan = Dib.ColorBits() / 8 ; // 3 or 4
		for (int y=rcDest.top ; y < rcDest.bottom ; y++)
		{
			BYTE		* pDest = this->GetBits (rcDest.left, y) ;
			BYTE		* pSrc = Dib.GetBits (y - rcDest.top) ;
			for (int x=rcDest.left ; x < rcDest.right ; x++, pDest += nNewSpan, pSrc += nOldSpan)
			{
				switch (dwRop)
				{
					case LOG_OPERATION_AND :
						pDest[0] &= pSrc[0] ; pDest[1] &= pSrc[1] ; pDest[2] &= pSrc[2] ; break ;
					case LOG_OPERATION_OR :
						pDest[0] |= pSrc[0] ; pDest[1] |= pSrc[1] ; pDest[2] |= pSrc[2] ; break ;
					case LOG_OPERATION_XOR :
						pDest[0] ^= pSrc[0] ; pDest[1] ^= pSrc[1] ; pDest[2] ^= pSrc[2] ; break ;
					case LOG_OPERATION_ADD :
						pDest[0] = max (0, min (0xFF, pSrc[0] + pDest[0])) ;
						pDest[1] = max (0, min (0xFF, pSrc[1] + pDest[1])) ;
						pDest[2] = max (0, min (0xFF, pSrc[2] + pDest[2])) ; break ;
					case LOG_OPERATION_SUB :
						pDest[0] = max (0, min (0xFF, pSrc[0] - pDest[0])) ;
						pDest[1] = max (0, min (0xFF, pSrc[1] - pDest[1])) ;
						pDest[2] = max (0, min (0xFF, pSrc[2] - pDest[2])) ; break ;
					case LOG_OPERATION_MUL :
						pDest[0] = max (0, min (0xFF, pSrc[0] * pDest[0])) ;
						pDest[1] = max (0, min (0xFF, pSrc[1] * pDest[1])) ;
						pDest[2] = max (0, min (0xFF, pSrc[2] * pDest[2])) ; break ;
				}
			}
		}
	}
}
//===================================================================
void  FCDib::AlphaBlend (const FCDib & Dib, int alpha, int x, int y)
{
	RECT	dib1 = {0, 0, Width(), Height()},
			dib2 = {x, y, x + Dib.Width(), y + Dib.Height()},
			rcDest ;
	if ((::IntersectRect (&rcDest, &dib1, &dib2) != 0) && (Dib.ColorBits() >= 24) && (this->ColorBits() >= 24))
	{
		int			nNewSpan = this->ColorBits() / 8,
					nOldSpan = Dib.ColorBits() / 8 ; // 3 or 4
		for (int y=rcDest.top ; y < rcDest.bottom ; y++)
		{
			BYTE		* pDest = this->GetBits (rcDest.left, y) ;
			BYTE		* pSrc = Dib.GetBits (y - rcDest.top) ;
			for (int x=rcDest.left ; x < rcDest.right ; x++, pDest += nNewSpan, pSrc += nOldSpan)
			{
				pDest[0] = max (0, min (0xFF, (pSrc[0] - pDest[0]) * alpha / 0xFF + pDest[0])) ;
				pDest[1] = max (0, min (0xFF, (pSrc[1] - pDest[1]) * alpha / 0xFF + pDest[1])) ;
				pDest[2] = max (0, min (0xFF, (pSrc[2] - pDest[2]) * alpha / 0xFF + pDest[2])) ;
			}
		}
	}
}
//===================================================================
void  FCDib::AlphaBlend (const FCDib & Dib32, int x, int y)
{
	RECT	dib1 = {0, 0, Width(), Height()},
			dib2 = {x, y, x + Dib32.Width(), y + Dib32.Height()},
			rcDest ;
	if ((::IntersectRect (&rcDest, &dib1, &dib2) != 0) && (Dib32.ColorBits() == 32) && (this->ColorBits() >= 24))
	{
		int			nSpan = this->ColorBits() / 8 ; // 3 or 4
		for (int y=rcDest.top ; y < rcDest.bottom ; y++)
		{
			BYTE		* pDest = this->GetBits (rcDest.left, y) ;
			RGBQUAD		* pSrc = (RGBQUAD *) Dib32.GetBits (y - rcDest.top) ;
			for (int x=rcDest.left ; x < rcDest.right ; x++, pDest += nSpan, pSrc++)
			{
				pDest[0] = max (0, min (0xFF, (pSrc->rgbBlue - pDest[0]) * pSrc->rgbReserved / 0xFF + pDest[0])) ;
				pDest[1] = max (0, min (0xFF, (pSrc->rgbGreen - pDest[1]) * pSrc->rgbReserved / 0xFF + pDest[1])) ;
				pDest[2] = max (0, min (0xFF, (pSrc->rgbRed - pDest[2]) * pSrc->rgbReserved / 0xFF + pDest[2])) ;
			}
		}
	}
}
//===================================================================

⌨️ 快捷键说明

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