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

📄 enbitmap.cpp

📁 If you are not using these features and wish to reduce the size
💻 CPP
📖 第 1 页 / 共 3 页
字号:
								bmInfo.bmiColors[i].rgbGreen;
				pLP->palPalEntry[cx].peBlue = bmInfo.bmiColors[i].rgbBlue;
				pLP->palPalEntry[cx].peFlags = PC_RESERVED;
				cx++;
			}
		}

	}
	else if (nColors)
	{
		// We have enough room for all the colors
		
		pLP->palNumEntries = nColors;
		
		// Copy the colors
		for(int i = 0; i < nColors; i++)
		{
			pLP->palPalEntry[i].peRed = bmInfo.bmiColors[i].rgbRed;
			pLP->palPalEntry[i].peGreen = bmInfo.bmiColors[i].rgbGreen;
			pLP->palPalEntry[i].peBlue = bmInfo.bmiColors[i].rgbBlue;
			pLP->palPalEntry[i].peFlags = PC_RESERVED;
		}
	}
	

	hPal = CreatePalette( pLP );
	delete[] pLP;
	
	// return handle to DIB's palette 
	return hPal;
}

// FadeColorToGrayScale	- Draws a bitmap in color slowly turns it to grayscale
// pDC				- Pointer to target device context
// hDIB				- Handle of device-independent bitmap
// xDest			- x-coordinate of upper-left corner of dest. rect. 
// yDest			- y-coordinate of upper-left corner of dest. rect. 
// nLoops			- How many loops to fade the image into color
// nDelay			- Delay in milli-seconds between each loop
//
void CEnBitmap::FadeColorToGrayScale( CDC *pDC,int xDest, int yDest, int nLoops, 
									int nDelay ) 
{
	CPalette pal;
	CPalette *pOldPalette;
	PALETTEENTRY peAnimate[256];
	PALETTEENTRY peGray[256];
	PALETTEENTRY peOriginal[256];

	HBITMAP hBmp = (HBITMAP)this->GetSafeHandle();
	// get image properties
	//BITMAP bmp = { 0 };
	//::GetObject( hBmp, sizeof(BITMAP), &bmp );
	// allocate memory for extended image information
	BITMAPINFO &bmInfo= *(LPBITMAPINFO) new BYTE[ sizeof(BITMAPINFO) + 8 ];
	memset( &bmInfo, 0, sizeof(BITMAPINFO) + 8 );
	bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);

	// get extended information about image (length, compression, length of color table if exist, ...)
	DWORD res = GetDIBits(pDC->GetSafeHdc() , hBmp, 0, GetHeight(), 0, &bmInfo, DIB_RGB_COLORS );
	// allocate memory for image data (colors)
	LPBYTE pBits = new BYTE[ bmInfo.bmiHeader.biSizeImage + 4 ];

	res = GetDIBits( pDC->GetSafeHdc(), hBmp, 0,  bmInfo.bmiHeader.biHeight, pBits, &bmInfo, DIB_RGB_COLORS );

    int nColors = bmInfo.bmiHeader.biClrUsed ? bmInfo.bmiHeader.biClrUsed : 
                1 << bmInfo.bmiHeader.biBitCount;
    
    int nWidth = bmInfo.bmiHeader.biWidth;
    int nHeight = bmInfo.bmiHeader.biHeight;
    
    // Compute the address of the bitmap bits
    LPVOID lpDIBBits;
    if( bmInfo.bmiHeader.biBitCount > 8 )
        lpDIBBits = (LPVOID)((LPDWORD)(pBits + 
            bmInfo.bmiHeader.biClrUsed) + 
            ((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
    else
        lpDIBBits = (LPVOID)(pBits + nColors);
	
	int nReservedColors = nColors > 236 ? 236 : nColors;


	// Create the palette if needed
	if( pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE && nColors <= 256 )
	{
		// The device supports a palette and bitmap has color table
		
		HPALETTE hPal = CreateReservedPalette(pDC);
		pal.Attach( hPal );

		// Now save the original colors and get the grayscale colors
		pal.GetPaletteEntries(0, nReservedColors, (LPPALETTEENTRY)&peOriginal);
		for( int i=0; i < nReservedColors; i++)
		{
			int nGray = Grey( peOriginal[i].peRed, peOriginal[i].peGreen , peOriginal[i].peBlue );
			
			peGray[i].peRed = nGray;
			peGray[i].peGreen = nGray;
			peGray[i].peBlue = nGray;
		}


		
		// Select the palette
		pOldPalette = pDC->SelectPalette(&pal, FALSE);
		pDC->RealizePalette();
		
		::SetDIBitsToDevice(pDC->m_hDC, xDest, yDest, nWidth, nHeight, 0, 0, 0,
			nHeight, lpDIBBits, (LPBITMAPINFO)&bmInfo, DIB_RGB_COLORS);

		// Now animate palette to set the image to grayscale
		for( i=1; i <= nLoops; i++ )
		{
			for (int j = 0; j< nColors; j++) 
			{  
				peAnimate[j].peRed = peOriginal[j].peRed - 
					((peOriginal[j].peRed -peGray[j].peRed)*i)/nLoops;
				peAnimate[j].peGreen = peOriginal[j].peGreen - 
					((peOriginal[j].peGreen-peGray[j].peGreen)*i)
						/nLoops;
				peAnimate[j].peBlue = peOriginal[j].peBlue  - 
					((peOriginal[j].peBlue -peGray[j].peBlue)*i)/nLoops;

				peAnimate[j].peFlags = peOriginal[j].peFlags;
			}

			pal.AnimatePalette(0, nColors, (LPPALETTEENTRY)&peAnimate);

			// Delay...
			Sleep(nDelay);
		}

		// Select the old palette back
		pDC->SelectPalette(pOldPalette, FALSE);
	}
	else if( (pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE) == 0 && nColors <= 256 )
	{
		// Now change the image to grayscale
		for(int i=1; i <= nLoops; i++ )
		{
 
			BYTE *dst=(BYTE*)lpDIBBits;
			int Size=nWidth*nHeight;

			while ( Size-- )
			{
				int nGrey = Grey( dst[2], dst[1], dst[0] );

				dst[2]=(BYTE)dst[2] -((dst[2] -nGrey)*i)/nLoops;
				dst[1]=(BYTE)dst[1] -((dst[1] -nGrey)*i)/nLoops;
				dst[0]=(BYTE)dst[0] -((dst[0] -nGrey)*i)/nLoops;
				dst+=4;
			}

			// Draw the image again
			::SetDIBitsToDevice(pDC->m_hDC, xDest, yDest, nWidth, nHeight, 0, 
				0, 0, nHeight, lpDIBBits, (LPBITMAPINFO)&bmInfo, 
				DIB_RGB_COLORS);

			// Delay...
			Sleep(nDelay);
		}
	}
	else
	{
		::SetDIBitsToDevice(pDC->m_hDC, xDest, yDest, nWidth, nHeight, 0, 0, 0,
			nHeight, lpDIBBits, (LPBITMAPINFO)&bmInfo, DIB_RGB_COLORS);
	}
}

void CEnBitmap::AlphaDisplay(CDC  *pDC, BYTE bAlpha)
{
	CDC dc;
	dc.CreateCompatibleDC( pDC );
	CBitmap * bmp = dc.SelectObject( this );
      
	BLENDFUNCTION rBlendProps;
	rBlendProps.BlendOp = AC_SRC_OVER;
	rBlendProps.BlendFlags = 0;
	rBlendProps.AlphaFormat = 0;   
	rBlendProps.SourceConstantAlpha = bAlpha;
	BITMAP bmInfo;
	::GetObject(m_hObject, sizeof(BITMAP), &bmInfo );
	INT nWidth, nHeigh;
	nWidth = bmInfo.bmWidth;
	nHeigh = bmInfo.bmHeight;

    AlphaBlend(pDC->m_hDC, 0, 0, nWidth, nHeigh, dc.m_hDC , 0, 0, 
        nWidth, nHeigh, rBlendProps );
	dc.SelectObject( bmp );	
}

/* ExtCreateRegion replacement */
HRGN CEnBitmap::CreateRegionExt(DWORD nCount, CONST RGNDATA *pRgnData )
{
		HRGN hRgn=CreateRectRgn(0, 0, 0, 0);
		const DWORD RDHDR = sizeof(RGNDATAHEADER);
		ASSERT( hRgn!=NULL );
		LPRECT pRects = (LPRECT)((LPBYTE)pRgnData + RDHDR);
		for(int i=0;i<(int)nCount;i++)
		{
			HRGN hr=CreateRectRgn(pRects[i].left, pRects[i].top, pRects[i].right, pRects[i].bottom);
			VERIFY(CombineRgn(hRgn, hRgn, hr, RGN_OR)!=ERROR);
			if (hr) 
				::DeleteObject(hr);
		}
		ASSERT( hRgn!=NULL );
		return hRgn;
}

///////////////////////////////////////////////////////////////////
// InflateRegion - Inflates a region by the x and y values
// specified in nXInflate and nYInflate
// Creates a new region that represents the inflated region
// (retains the contents of the old region)
// Returns NULL if unsuccessfull
HRGN CEnBitmap::InflateRegion(HRGN hRgn, int nXInflate, int nYInflate)
{
	// Local Variables
	LPRGNDATA lpData;	// The RGNDATA structure
	LPRECT lpRect;		// Pointer to the array of RECT structures
	DWORD BufSize;		// The amount of memory required
	DWORD i;			// General index variable
	HRGN hRgnNew;		// The newly created region

	// Get the number of rectangles in the region
	BufSize = GetRegionData(hRgn, 0, NULL);
	if(BufSize == 0)
		return NULL;
	// Allocate memory for the RGNDATA structure
	lpData = (LPRGNDATA)malloc(BufSize);
	// Set the location of the RECT structures
	lpRect = (LPRECT)(lpData->Buffer);
	// Get the region data
	if(!GetRegionData(hRgn, BufSize, lpData))
	{
		free(lpData);
		return NULL;
	}
	// Expand (or contract) all the rectangles in the data
	for(i=0; i<lpData->rdh.nCount; i++)
		InflateRect(&lpRect[i], nXInflate, nYInflate);
	// Create the new region
	hRgnNew = CreateRegionExt(lpData->rdh.nCount, lpData);
	free((void*)lpData);
	return hRgnNew;
}

BOOL CEnBitmap::StretchDraw(CDC *pDC, LPRECT r, LPRECT sr )
{
	if ( !r ) 
		return FALSE;
	CDC dc;
	dc.CreateCompatibleDC( pDC );
	CBitmap * bmp = dc.SelectObject( this );
	//pDC->SetStretchBltMode(COLORONCOLOR);
	
	if ( !sr )
		pDC->StretchBlt( r->left, r->top, r->right, r->bottom, &dc, 0, 0, GetWidth(), GetHeight() ,
			SRCCOPY );
	else
		pDC->StretchBlt( r->left, r->top, r->right - r->left, r->bottom - r->top, &dc, sr->left, sr->top, 
		sr->right - sr->left, sr->bottom - sr->top,
			SRCCOPY );

	
	dc.SelectObject( bmp );	
	return TRUE;	

}

BOOL CEnBitmap::DrawImage(CEnBitmap &bmp,int nX,int nY,int nCol,int nRow)
{
	nX-=1;
	nY-=1;
	//单个图片的长和宽
	int w = GetWidth()/nCol;
	int h = GetHeight()/nRow;
	
	CBitmap *OldBmp;
	CDC memDC;
	CClientDC dc(0);

	memDC.CreateCompatibleDC(&dc);
	bmp.CreateCompatibleBitmap(&dc, w, h);
	OldBmp = memDC.SelectObject( &bmp );

	StretchDraw(&memDC, CRect( 0, 0, w, h ),CRect(GetWidth()*nX/nCol, GetHeight()*nY/nRow, GetWidth()*nX/nCol+w ,GetHeight()*nY/nRow+h ));

	memDC.SelectObject(OldBmp);
	return TRUE;
}

CRect CEnBitmap::GetRect()
{
	return CRect(0,0,GetWidth(),GetHeight());
}

HBITMAP CEnBitmap::SetBitmap(HBITMAP hBitmap)
{
	CEnBitmap *pBmp=(CEnBitmap *)CEnBitmap::FromHandle(hBitmap);
	HBITMAP hBmp=(HBITMAP)this->Detach(); 
	this->DeleteObject(); 
	pBmp->DrawImage(*this,1,1,1,1); 
	return hBmp;	
}

BOOL CEnBitmap::ExtendDraw(CDC *pDC,CRect rc, int nX, int nY)
{
	CEnBitmap bmp;
	if (ExtendDrawImage(bmp,rc,nX,nY))
	{
		bmp.Draw(pDC,&rc); 
		return TRUE;
	}
	return FALSE;
}

BOOL CEnBitmap::ExtendDrawImage(CEnBitmap &bmp,CRect rc, int nX, int nY)
{
	CBitmap *OldBmp;
	CDC memDC;
	CClientDC cdc(0);

	memDC.CreateCompatibleDC(&cdc);
	bmp.CreateCompatibleBitmap(&cdc, rc.Width() , rc.Height() );
	OldBmp = memDC.SelectObject( &bmp );

	if (nX==0 && nY==0)
	{
		StretchDraw(&memDC,&rc,GetRect());
		return TRUE;
	}
	CDC dc;
	dc.CreateCompatibleDC(&memDC);
	CBitmap * Bmp = dc.SelectObject( this );
	//dc.SetStretchBltMode(COLORONCOLOR);
	if (nX!=0 && nY==0)
	{

		//坐上角
		memDC.BitBlt( 0, 0, nX, rc.Height(), &dc, 0, 0,
				SRCCOPY );
		memDC.StretchBlt(nX, 0, rc.Width()-GetWidth(), rc.Height() ,  &dc,nX, 0, 1, GetHeight(),
				SRCCOPY );
		//右上角
		memDC.BitBlt(rc.right-(GetWidth()-nX), 0, GetWidth()-nX, rc.Height() ,  &dc,nX, 0, 
				SRCCOPY );

	}
	else if (nX==0 && nY!=0)
	{
		//上角
		memDC.BitBlt( 0, 0, rc.Width(), nY, &dc, 0, 0,
				SRCCOPY );
		memDC.StretchBlt(0, nY, GetWidth(), rc.Height()-GetHeight(),   &dc,0, nY, GetWidth(), 1,
				SRCCOPY );
		//右上角
		memDC.BitBlt(0, rc.bottom-(GetHeight()-nY), GetWidth(), GetHeight()-nY ,  &dc,0, nY, 
				SRCCOPY );
	
	}
	else
	{
		//坐上角
		memDC.StretchBlt( 0, 0, nX, nY, &dc, 0, 0, nX, nY ,
				SRCCOPY );
		//上中
		memDC.StretchBlt(nX, 0, rc.Width()-GetWidth(),nY, &dc, nX, 0, 1, nY ,
				SRCCOPY );
		//右上角
		memDC.StretchBlt(rc.Width()-(GetWidth()-nX), 0, GetWidth()-nX, nY ,  &dc,nX, 0, GetWidth()-nX, nY,
				SRCCOPY );
		//左中
		memDC.StretchBlt(0, nY, nX,rc.Height()-GetHeight(), &dc, 0, nY, nX, 1 ,
				SRCCOPY );
		//正中
		memDC.StretchBlt(nX, nY, rc.Width()-GetWidth(),rc.Height()-GetHeight(), &dc, nX, nY, 1, 1 ,
				SRCCOPY );
		//右中
		memDC.StretchBlt(rc.Width()-(GetWidth()-nX), nY, GetWidth()-nX,rc.Height()-GetHeight(), &dc, nX, nY, GetWidth()-nX, 1 ,
				SRCCOPY );

		//左下角
		memDC.StretchBlt( 0, rc.Height()-(GetHeight()-nY), nX, GetHeight()-nY, &dc, 0, nY, nX,GetHeight()-nY ,
				SRCCOPY );
		//下中
		memDC.StretchBlt(nX, rc.Height()-(GetHeight()-nY), rc.Width()-GetWidth(),GetHeight()-nY, &dc, nX, nY, 1, GetHeight()-nY ,
				SRCCOPY );
		//右下角
		memDC.StretchBlt( rc.Width()-(GetWidth()-nX), rc.Height()-(GetHeight()-nY), GetWidth()-nX, GetHeight()-nY, &dc, nX, nY, GetWidth()-nX,GetHeight()-nY ,
				SRCCOPY );
	}
	dc.SelectObject( Bmp );	
	memDC.SelectObject(OldBmp);

	return TRUE;
}

⌨️ 快捷键说明

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