Example #1
0
void CxImage::CreateFromHICON(HICON hico)
{
	Destroy();
	if (hico) { 
		ICONINFO iinfo;
		GetIconInfo(hico,&iinfo);
		CreateFromHBITMAP(iinfo.hbmColor);
#if CXIMAGE_SUPPORT_ALPHA
		CxImage mask;
		mask.CreateFromHBITMAP(iinfo.hbmMask);
		mask.GrayScale();
		mask.Negative();
		AlphaSet(mask);
#endif
    }
}
std::string UserListModule_Impl::getGrayLocalPathFromFilename(std::string& finename)
{
	CString csFileName = util::stringToCString(finename);
	CString csGrayAvatarPath = module::getMiscModule()->getDownloadDir() + PREFIX_GRAY_AVATAR + csFileName;
	//本地磁盘存在
	if (util::isFileExist(csGrayAvatarPath))
	{
		return util::cStringToString(csGrayAvatarPath);
	}
	else
	{
		//不存在则对图片做灰度处理并且保存到本地
		CxImage cximage;
		CString csAvatarPath = module::getMiscModule()->getDownloadDir() + csFileName;
		bool bSucc = cximage.Load(csAvatarPath);
		if (bSucc)
		{
			cximage.GrayScale();
			module::getCaptureModule()->saveToFile(cximage.MakeBitmap(), csAvatarPath);
		}
	}

	return "";
}
Example #3
0
bool IGIPFilter::OnImageProcessing (CxImage& image, IGImageProcMessage& message)
{
	IGIPFilterMessage *pIGThreadMessage = dynamic_cast <IGIPFilterMessage *> (&message);
	_ASSERTE (pIGThreadMessage && L"Wrong IGThread message, image processing aborted");
	if (!pIGThreadMessage || !m_pFrame)
		return false;
	IGLayer *pLayer = m_pFrame->GetLayer (m_pFrame->GetLayerPos (image.GetWorkingLayer()));
	if (!pLayer)
		return false;

	switch (pIGThreadMessage->m_eFilterType)
	{
	case IGIPFILTER_BLUR:
		return pLayer->GaussianBlur (5.0f);
	case IGIPFILTER_GRADIENT:
		{
			long tKernel [9];
			pLayer->GrayScale();
			CxImage g1(*pLayer), g2(*pLayer), g3(*pLayer), g4(*pLayer);
			tKernel[0] = 0;tKernel[1] = 1;tKernel[2] = -1;
			tKernel[3] = 0;tKernel[4] = 1;tKernel[5] = -1;
			tKernel[6] = 0;tKernel[7] = 1;tKernel[8] = -1;
			g1.Filter (tKernel, 3, 4, 0);
			tKernel[0] = -1;tKernel[1] = 1;tKernel[2] = 0;
			tKernel[3] = -1;tKernel[4] = 1;tKernel[5] = 0;
			tKernel[6] = -1;tKernel[7] = 1;tKernel[8] = 0;
			g2.Filter (tKernel, 3, 4, 0);
			tKernel[0] = -1;tKernel[1] = -1;tKernel[2] = -1;
			tKernel[3] = 1;tKernel[4] = 1;tKernel[5] = 1;
			tKernel[6] = 0;tKernel[7] = 0;tKernel[8] = 0;
			g3.Filter (tKernel, 3, 4, 0);
			tKernel[0] = 0;tKernel[1] = 0;tKernel[2] = 0;
			tKernel[3] = 1;tKernel[4] = 1;tKernel[5] = 1;
			tKernel[6] = -1;tKernel[7] = -1;tKernel[8] = -1;
			g4.Filter (tKernel, 3, 4, 0);
			pLayer->Copy (g1, true, false, false, false);
			*pLayer += g2;
			*pLayer += g3;
			*pLayer += g4;
			return true;
		}
	case IGIPFILTER_GRADIENT_MORPHO:
		return pLayer->ComputeGradient (true);
	case IGIPFILTER_GRAY:
		return pLayer->GrayScale();
	case IGIPFILTER_SKIN:
		return pLayer->FilterSkin();
	case IGIPFILTER_SKIN_UNNOISED:
		return pLayer->FilterSkinUnnoised();
	case IGIPFILTER_EYES:
		{
			RECT rcNo = {-1,-1,-1,-1};
			return pLayer->RedEyeRemove (rcNo, rcNo, 0.5f);
		}
	case IGIPFILTER_EYES_COLOR:
		{
			RECT rcNo = {-1,-1,-1,-1};
			RGBQUAD rgbq;
			IGTexture texture;
			if (!m_pFrame->GetProperty (IGProperties::IGPROPERTY_CURTEXTURE, texture))
				return false;
			COLORREF col = (COLORREF)texture;
			rgbq.rgbRed = GetRValue (col);
			rgbq.rgbBlue = GetBValue (col);
			rgbq.rgbGreen = GetGValue (col);
			rgbq.rgbReserved = 0x00;
			rgbq = pLayer->RGBtoHSL (rgbq);
			return pLayer->ChangeEyeColor (rcNo, rcNo, rgbq.rgbRed, rgbq.rgbGreen, 50.0f);
		}
	case IGIPFILTER_FFT:
		{
			CxImage copy (*pLayer);
			copy.GrayScale();
			CxImage res;
			if (!pLayer->FFT2 (&copy, NULL, &res, NULL))
				return false;
			pLayer->Copy (res);
			return true;
		}
	case IGIPFILTER_FACE_EFFECT:
		{
			IGIPFaceEffectMessage *pIGIPFaceEffectMessage = dynamic_cast <IGIPFaceEffectMessage *> (pIGThreadMessage);
			_ASSERTE (pIGIPFaceEffectMessage && L"Wrong IGThread message, face effect image processing aborted");
			if (!pIGIPFaceEffectMessage)
				return false;
			return pLayer->ProcessFaceEffect (pIGIPFaceEffectMessage);
		}
	case IGIPFILTER_COLORIZE:
		{
			RGBQUAD rgbq;
			IGTexture texture;
			if (!m_pFrame->GetProperty (IGProperties::IGPROPERTY_CURTEXTURE, texture))
				return false;
			COLORREF col = (COLORREF)texture;
			rgbq.rgbRed = GetRValue (col);
			rgbq.rgbBlue = GetBValue (col);
			rgbq.rgbGreen = GetGValue (col);
			rgbq.rgbReserved = 0x00;
			rgbq = pLayer->RGBtoHSL (rgbq);
			return pLayer->Colorize (rgbq.rgbRed, rgbq.rgbGreen, rgbq.rgbBlue, (float)texture.GetTransparency() / 255.0f);
		}
	case IGIPFILTER_BRIGHTNESS:
		{
			int nStrength = -1;
			if (!m_pFrame->GetRequestProperty(IGIPFILTER_PARAM_STRENGTH, nStrength) || (nStrength == -1))
				return false;
			return pLayer->Light ((long)((float)nStrength * 2.55f));
		}
	case IGIPFILTER_CONTRAST:
		{
			int nStrength = -1;
			if (!m_pFrame->GetRequestProperty(IGIPFILTER_PARAM_STRENGTH, nStrength) || (nStrength == -1))
				return false;
			return pLayer->Light (0, nStrength);
		}
	case IGIPFILTER_SATURATE:
		{
			int nStrength = -1;
			if (!m_pFrame->GetRequestProperty(IGIPFILTER_PARAM_STRENGTH, nStrength) || (nStrength == -1))
				return false;
			return pLayer->Saturate (nStrength);
		}
	case IGIPFILTER_VIBRANCE:
		{
			int nStrength = -1;
			if (!m_pFrame->GetRequestProperty(IGIPFILTER_PARAM_STRENGTH, nStrength) || (nStrength == -1))
				return false;
			return pLayer->Vibrance ((long)((float)nStrength * 2.55f));
		}
	case IGIPFILTER_MORPHING:
		{
			int nRadius = -1, nType = -1, nPosX = -1, nPosY = -1, nDirectionX = 0, nDirectionY = 0;
			if (!m_pFrame->GetRequestProperty(IGIPFILTER_PARAM_STRENGTH, nRadius) || (nRadius == -1))
				return false;
			if (!m_pFrame->GetRequestProperty(IGIPFILTER_PARAM_TYPE, nType) || (nType == -1))
				return false;
			if (!m_pFrame->GetRequestProperty(IGIPFILTER_PARAM_POSX, nPosX) || (nPosX == -1))
				return false;
			if (!m_pFrame->GetRequestProperty(IGIPFILTER_PARAM_POSY, nPosY) || (nPosY == -1))
				return false;
			if (!m_pFrame->GetRequestProperty(IGIPFILTER_PARAM_DIRECTIONX, nDirectionX))
				return false;
			if (!m_pFrame->GetRequestProperty(IGIPFILTER_PARAM_DIRECTIONY, nDirectionY))
				return false;
			// convert DZ coords to IG
			double dSeadragonToPixelRatioX, dSeadragonToPixelRatioY;
			IGConvertible::FromDZtoIGRatios (image.GetWidth(), image.GetHeight(), dSeadragonToPixelRatioX, dSeadragonToPixelRatioY);
			POINT ptPos; ptPos.x = (int)((double)nPosX * dSeadragonToPixelRatioX); ptPos.y = (int)((double)nPosY * dSeadragonToPixelRatioY);
			POINT ptDir; ptDir.x = (int)((double)nDirectionX * dSeadragonToPixelRatioX); ptDir.y = (int)((double)nDirectionY * dSeadragonToPixelRatioY);
			// convert IG coords to CX
			IGConvertible::FromIGtoCxCoords(ptPos, image.GetHeight());
			ptDir.y *= -1;
			// apply morphing
			return pLayer->Morphing (ptPos.x, ptPos.y, (float)ptDir.x, (float)ptDir.y, (float)nRadius, nType);
		}
	case IGIPFILTER_NEGATIVE:
			return pLayer->Negative();
	case IGIPFILTER_TRANSPARENCY:
		{
			int nAlpha = 0;
			if (!m_pFrame->GetRequestProperty(IGIPFILTER_PARAM_STRENGTH, nAlpha))
				return false;
			pLayer->AlphaDelete();
			return pLayer->AlphaCreate ((BYTE)((float)nAlpha * 2.55f));
		}
	case IGIPFILTER_PAINT:
		{
			int nPosX = -1, nPosY = -1;
			if (!m_pFrame->GetRequestProperty(IGIPFILTER_PARAM_POSX, nPosX) || (nPosX == -1))
				return false;
			if (!m_pFrame->GetRequestProperty(IGIPFILTER_PARAM_POSY, nPosY) || (nPosY == -1))
				return false;
			int nTolerance = 0;
			if (!m_pFrame->GetRequestProperty(IGIPFILTER_PARAM_TOLERANCE, nTolerance))
				return false;
			RGBQUAD rgbq;
			IGTexture texture;
			if (!m_pFrame->GetProperty (IGProperties::IGPROPERTY_CURTEXTURE, texture))
				return false;
			// convert DZ coords to IG
			double dSeadragonToPixelRatioX, dSeadragonToPixelRatioY;
			IGConvertible::FromDZtoIGRatios (image.GetWidth(), image.GetHeight(), dSeadragonToPixelRatioX, dSeadragonToPixelRatioY);
			POINT ptPos; ptPos.x = (int)((double)nPosX * dSeadragonToPixelRatioX); ptPos.y = (int)((double)nPosY * dSeadragonToPixelRatioY);
			// convert IG coords to CX
			IGConvertible::FromIGtoCxCoords(ptPos, image.GetHeight());
			COLORREF col = (COLORREF)texture;
			rgbq.rgbRed = GetRValue (col);
			rgbq.rgbBlue = GetBValue (col);
			rgbq.rgbGreen = GetGValue (col);
			rgbq.rgbReserved = 0x00;			
			return pLayer->FloodFill (ptPos.x, ptPos.y, rgbq, nTolerance);
		}
	case IGIPFILTER_PAINTGRADIENT:
		{
			int nPosX = -1, nPosY = -1, nDirectionX = 0, nDirectionY = 0;
			if (!m_pFrame->GetRequestProperty(IGIPFILTER_PARAM_POSX, nPosX) || (nPosX == -1))
				return false;
			if (!m_pFrame->GetRequestProperty(IGIPFILTER_PARAM_POSY, nPosY) || (nPosY == -1))
				return false;
			if (!m_pFrame->GetRequestProperty(IGIPFILTER_PARAM_DIRECTIONX, nDirectionX))
				return false;
			if (!m_pFrame->GetRequestProperty(IGIPFILTER_PARAM_DIRECTIONY, nDirectionY))
				return false;
			RGBQUAD rgbq, rgbqBkgnd;
			IGTexture texture, bkgndTexture;
			if (!m_pFrame->GetProperty (IGProperties::IGPROPERTY_CURTEXTURE, texture))
				return false;
			COLORREF col = (COLORREF)texture;
			rgbq.rgbRed = GetRValue (col);
			rgbq.rgbBlue = GetBValue (col);
			rgbq.rgbGreen = GetGValue (col);
			rgbq.rgbReserved = 0x00;	
			if (!m_pFrame->GetProperty (IGProperties::IGPROPERTY_BKGNDTEXTURE, bkgndTexture))
				return false;
			// convert DZ coords to IG
			double dSeadragonToPixelRatioX, dSeadragonToPixelRatioY;
			IGConvertible::FromDZtoIGRatios (image.GetWidth(), image.GetHeight(), dSeadragonToPixelRatioX, dSeadragonToPixelRatioY);
			POINT ptPos; ptPos.x = (int)((double)nPosX * dSeadragonToPixelRatioX); ptPos.y = (int)((double)nPosY * dSeadragonToPixelRatioY);
			POINT ptDir; ptDir.x = (int)((double)nDirectionX * dSeadragonToPixelRatioX); ptDir.y = (int)((double)nDirectionY * dSeadragonToPixelRatioY);
			// convert IG coords to CX
			IGConvertible::FromIGtoCxCoords(ptPos, image.GetHeight());
			ptDir.y *= -1;
			COLORREF colBkgnd = (COLORREF)bkgndTexture;
			rgbqBkgnd.rgbRed = GetRValue (colBkgnd);
			rgbqBkgnd.rgbBlue = GetBValue (colBkgnd);
			rgbqBkgnd.rgbGreen = GetGValue (colBkgnd);
			rgbqBkgnd.rgbReserved = 0x00;	
			return pLayer->FillGradient (ptPos.x, ptPos.y, ptDir.x, ptDir.y, rgbq, rgbqBkgnd);
		}
	case IGIPFILTER_REPAIR:
		return pLayer->Repair (0.25f, 3, 0);
	case IGIPFILTER_SHARPEN:
		return pLayer->UnsharpMask (5.0f, 0.5f, 0);	
	case IGIPFILTER_MATIFY:
		{
			COLORREF col = IGIPFACE_EFFECT_MATIFY_COLORCODE;
			RGBQUAD rgbq;
			rgbq.rgbRed = GetRValue (col);
			rgbq.rgbBlue = GetBValue (col);
			rgbq.rgbGreen = GetGValue (col);
			rgbq.rgbReserved = 0x00;
			rgbq = pLayer->RGBtoHSL (rgbq);
			return pLayer->Colorize (rgbq.rgbRed, rgbq.rgbGreen, rgbq.rgbBlue, 1.0f);
		}
	case IGIPFILTER_THRESHOLD:
		return pLayer->AdaptiveThreshold(0);
	case IGIPFILTER_AUTOROTATE:
		return pLayer->AutoRotate();
	case IGIPFILTER_SKETCH:
		return pLayer->Sketch();
	case IGIPFILTER_CARTOON:
		return pLayer->Cartoon();
	case IGIPFILTER_OILPAINTING:
		return pLayer->OilPainting();
	case IGIPFILTER_WATERPAINTING:
		return pLayer->WaterPainting();
	case IGIPFILTER_SEPIA:
		{
			RGBQUAD rgbq;
			rgbq.rgbRed = 112;
			rgbq.rgbBlue = 20;
			rgbq.rgbGreen = 66;
			rgbq.rgbReserved = 0x00;
			rgbq = pLayer->RGBtoHSL (rgbq);
			return pLayer->Colorize (rgbq.rgbRed, rgbq.rgbGreen, rgbq.rgbBlue, 1.0f);
		}
	case IGIPFILTER_VINTAGE:
		{
			pLayer->UnsharpMask (5.0f, 0.5f, 0);	
			pLayer->UnsharpMask (5.0f, 0.5f, 0);	
			pLayer->UnsharpMask (5.0f, 0.5f, 0);	
			RGBQUAD rgbq;
			rgbq.rgbRed = 112;
			rgbq.rgbBlue = 20;
			rgbq.rgbGreen = 66;
			rgbq.rgbReserved = 0x00;
			rgbq = pLayer->RGBtoHSL (rgbq);
			return pLayer->Colorize (rgbq.rgbRed, rgbq.rgbGreen, rgbq.rgbBlue, 0.25f);
		}
	case IGIPFILTER_DITHER:
		return pLayer->Dither();
	case IGIPFILTER_CLAY:
		return pLayer->Clay();
	case IGIPFILTER_PYTHON:
		{
			wstring wsPythonScript;
			if (!m_pFrame->GetRequestProperty(IGIPFILTER_PARAM_SCRIPT, wsPythonScript))
				return false;
			return pLayer->ExecutePythonScript (wsPythonScript);
		}
	case IGIPFILTER_FILTER1:
		{
			CxImage *layer1 (*pLayer);
			CxImage *layer2 (*pLayer);
			CxImage *layer3 (*pLayer);
			int nAlpha = 0;

			// Contrast the image using the curve: out 116, in 139
			long contrast_in = 139, contrast_out = 116;
			CxImage *contrast_IN (*pLayer);
			CxImage *contrast_OUT (*pLayer);
			contrast_IN->Mix(*contrast_OUT); 

			contrast_IN->Light(0, contrast_in);
			contrast_OUT->Light(0, contrast_out);

			// Add contrast IN & OUT images
			// Apply layer 2 as screen with opacity 48
			nAlpha = 48;
			layer2->AlphaDelete();
			layer2->AlphaCreate ((BYTE)((float)nAlpha * 2.55f));

			// Apply layer 3 as overlay with opacity 35
			nAlpha = 35;
			layer3->AlphaDelete();
			layer3->AlphaCreate ((BYTE)((float)nAlpha * 2.55f));

			// Adding the three layers 
			layer1->Mix(*layer2);
			layer1->Mix(*layer3);

			return true;
		}

	case IGIPFILTER_PAPER:
		return pLayer->Paper();

	case IGIPFILTER_HALOSEPIA:
		return pLayer->Sepia();		

	case IGIPFILTER_BW:
		return pLayer->BlackAndWhite();
	}

	return false;
}
Example #4
0
//=============================================================================
//
//	The framework calls this member function when a child control is about to 
//	be drawn.  All the bitmaps are created here on the first call. Every thing
//	is done with a memory DC except the background, which get's it's information 
//	from the parent. The background is needed for transparent portions of PNG 
//	images. An always on top app (such as Task Manager) that is in the way can 
//	cause it to get an incorrect background.  To avoid this, the parent should 
//	call the SetBkGnd function with a memory DC when it creates the background.
//				
//=============================================================================
HBRUSH CButtonBT::CtlColor(CDC* pScreenDC, UINT nCtlColor) 
{
	if(!m_bHaveBitmaps)
	{
		if(!m_imgStd.IsValid())
		{
			return NULL; // Load the standard image with LoadStdImage()
		}

		CBitmap bmp, *pOldBitmap;

		CRect rect;
		GetClientRect(rect);

		// do everything with mem dc
		CMemDCEx memdc(pScreenDC, rect);
		//CGDIPMemDC pDC(pScreenDC, rect);

		//Gdiplus::Graphics graphics(pDC->m_hDC);

		// background
		if (m_dcBk.m_hDC == NULL)
		{

			CRect rect1;
			CClientDC clDC(GetParent());
			GetWindowRect(rect1);
			GetParent()->ScreenToClient(rect1);

			m_dcBk.CreateCompatibleDC(&clDC);
			bmp.CreateCompatibleBitmap(&clDC, rect.Width(), rect.Height());
			pOldBitmap = m_dcBk.SelectObject(&bmp);
			m_dcBk.BitBlt(0, 0, rect.Width(), rect.Height(), &clDC, rect1.left, rect1.top, SRCCOPY);
			bmp.DeleteObject();
		}

		// standard image
		if (m_dcStd.m_hDC == NULL)
		{
			PaintBk(&memdc);

			//graphics.DrawImage(*m_pStdImage, 0, 0);
			m_imgStd.Draw(memdc.GetSafeHdc());
		
			m_dcStd.CreateCompatibleDC(&memdc);
			bmp.CreateCompatibleBitmap(&memdc, rect.Width(), rect.Height());
			pOldBitmap = m_dcStd.SelectObject(&bmp);
			m_dcStd.BitBlt(0, 0, rect.Width(), rect.Height(), &memdc, 0, 0, SRCCOPY);
			bmp.DeleteObject();

			// standard image pressed
			if (m_dcStdP.m_hDC == NULL)
			{
				PaintBk(&memdc);

				if (m_bISMove)
				{
					//graphics.DrawImage(*m_pStdImage, 1, 1);
					m_imgStd.Draw(memdc.GetSafeHdc(), 1, 1);
				}
				else
				{
					//graphics.DrawImage(*m_pStdImage, 0, 0);
					m_imgStd.Draw(memdc.GetSafeHdc());
				}
				

				m_dcStdP.CreateCompatibleDC(&memdc);
				bmp.CreateCompatibleBitmap(&memdc, rect.Width(), rect.Height());
				pOldBitmap = m_dcStdP.SelectObject(&bmp);
				m_dcStdP.BitBlt(0, 0, rect.Width(), rect.Height(), &memdc, 0, 0, SRCCOPY);
				bmp.DeleteObject();
			}

			// standard image hot
			if(m_dcStdH.m_hDC == NULL)
			{
				PaintBk(&memdc);

				CxImage imgtemp = m_imgStd;
				imgtemp.ShiftRGB(20,20,20);
				imgtemp.Draw(memdc.GetSafeHdc());
				m_dcStdH.CreateCompatibleDC(&memdc);
				bmp.CreateCompatibleBitmap(&memdc, rect.Width(), rect.Height());
				pOldBitmap = m_dcStdH.SelectObject(&bmp);
				m_dcStdH.BitBlt(0, 0, rect.Width(), rect.Height(), &memdc, 0, 0, SRCCOPY);
				bmp.DeleteObject();
			}

			// grayscale image
			if(m_dcGS.m_hDC == NULL)
			{
				PaintBk(&memdc);

				CxImage imgtemp = m_imgStd;
				imgtemp.GrayScale();
				imgtemp.Draw(memdc.GetSafeHdc());
				m_dcGS.CreateCompatibleDC(&memdc);
				bmp.CreateCompatibleBitmap(&memdc, rect.Width(), rect.Height());
				pOldBitmap = m_dcGS.SelectObject(&bmp);
				m_dcGS.BitBlt(0, 0, rect.Width(), rect.Height(), &memdc, 0, 0, SRCCOPY);
				bmp.DeleteObject();
			}
		}

		// alternate image
		if( (m_dcAlt.m_hDC == NULL) && m_bHaveAltImage )
		{
			PaintBk(&memdc);

			//graphics.DrawImage(*m_pAltImage, 0, 0);
			m_imgAlt.Draw(memdc.GetSafeHdc());
		
			m_dcAlt.CreateCompatibleDC(&memdc);
			bmp.CreateCompatibleBitmap(&memdc, rect.Width(), rect.Height());
			pOldBitmap = m_dcAlt.SelectObject(&bmp);
			m_dcAlt.BitBlt(0, 0, rect.Width(), rect.Height(), &memdc, 0, 0, SRCCOPY);
			bmp.DeleteObject();

			// alternate image pressed
			if( (m_dcAltP.m_hDC == NULL) && m_bHaveAltImage )
			{
				PaintBk(&memdc);

				if (m_bISMove)
				{
					//graphics.DrawImage(*m_pAltImage, 1, 1);
					m_imgAlt.Draw(memdc.GetSafeHdc(), 1, 1);
				}
				else
				{
					//graphics.DrawImage(*m_pAltImage, 0, 0);
					m_imgAlt.Draw(memdc.GetSafeHdc());
				}
				
			
				m_dcAltP.CreateCompatibleDC(&memdc);
				bmp.CreateCompatibleBitmap(&memdc, rect.Width(), rect.Height());
				pOldBitmap = m_dcAltP.SelectObject(&bmp);
				m_dcAltP.BitBlt(0, 0, rect.Width(), rect.Height(), &memdc, 0, 0, SRCCOPY);
				bmp.DeleteObject();
			}

			// alternate image hot
			if(m_dcAltH.m_hDC == NULL)
			{
				PaintBk(&memdc);

				CxImage imgtemp = m_imgAlt;
				imgtemp.ShiftRGB(20,20,20);
				imgtemp.Draw(memdc.GetSafeHdc());
				m_dcAltH.CreateCompatibleDC(&memdc);
				bmp.CreateCompatibleBitmap(&memdc, rect.Width(), rect.Height());
				pOldBitmap = m_dcAltH.SelectObject(&bmp);
				m_dcAltH.BitBlt(0, 0, rect.Width(), rect.Height(), &memdc, 0, 0, SRCCOPY);
				bmp.DeleteObject();
			}
		}

		if(m_pCurBtn == NULL)
		{
			m_pCurBtn = &m_dcStd;
		}

		m_bHaveBitmaps = TRUE;
	}

	return NULL;
}
Example #5
0
// This must be called before any frame-saving is attempted.
void CAnimationExporter::CreateGif()
{
    if(!g_canvas || !g_canvas->model || !g_canvas->model->animManager)
    {
        wxMessageBox(_T("Unable to create animated GIF!"), _T("Error") );
        wxLogMessage(_T(
            "Error: Unable to created animated GIF.  A required objects pointer was null!") );
        Show(false);
        return ;
    }

    CxImage **gifImages = NULL; // Our pointer array of images

    // Reset the state of our GUI objects
    btnStart->Enable(false);
    btnCancel->Enable(false);
    cbGrey->Enable(false);
    cbTrans->Enable(false);
    cbDither->Enable(false);
    cbShrink->Enable(false);
    txtFrames->Enable(false);
    txtSizeX->Enable(false);
    txtSizeY->Enable(false);
    txtDelay->Enable(false);

    // Pause our rendering to screen so we can focus on making the animated image
    g_videoSetting.render = false;

    m_fAnimSpeed = g_canvas->model->animManager->GetSpeed(); 
        // Save the old animation speed
    g_canvas->model->animManager->SetSpeed(1.0f); // Set it to the normal speed.

    m_iTotalAnimFrames = g_canvas->model->animManager->GetFrameCount();
    wxString(txtFrames->GetValue() ).ToLong( (long*) &m_iTotalFrames);
    wxString(txtDelay->GetValue() ).ToLong( (long*) &m_iDelay);

    // will crash program - prevent this from happening
    if(m_iTotalFrames > m_iTotalAnimFrames)
    {
        wxMessageBox(_T(
            "Impossible to make a gif with more frames than the model animation.\nClosing gif exporter."), _T("Error") );
        wxLogMessage(_T(
            "Error: Unable to make a gif with more frames than the model animation.") );
        this->Show(false);
        return ;
    }

    if(m_iDelay < 1)
    {
        m_iDelay = 1;
    }
    if(m_iDelay > 100)
    {
        m_iDelay = 100;
    }

    m_iTimeStep = int(m_iTotalAnimFrames / m_iTotalFrames); 
        // Total number of frames in the animation / total frames going into our exported animation image

    if(m_bShrink)
    {
        wxString(txtSizeX->GetValue() ).ToLong( (long*) &m_iNewWidth);
        wxString(txtSizeY->GetValue() ).ToLong( (long*) &m_iNewHeight);

        // Just a minor check,  final image size can not be smaller than 32x32 pixels.
        if(m_iNewWidth < 32 || m_iNewHeight < 32)
        {
            m_iNewWidth = 32;
            m_iNewHeight = 32;
        }
    }

    // CREATE OUR RENDERTOTEXTURE OBJECT
    // -------------------------------------------
    // if either are supported use our 'RenderTexture' object.
    if(g_videoSetting.supportPBO || g_videoSetting.supportVBO)
    {
        g_canvas->rt = new RenderTexture();

        if(!g_canvas->rt)
        {
            wxLogMessage(_T("Error: RenderToTexture object is null!") );
            this->Show(false);
            return ;
        }

        g_canvas->rt->Init( (HWND)g_canvas->GetHandle(), 0, 0, g_videoSetting.supportFBO)
            ;

        m_iWidth = g_canvas->rt->nWidth;
        m_iHeight = g_canvas->rt->nHeight;
        g_canvas->rt->BeginRender();
    }
    else
    {
        glReadBuffer(GL_BACK);
        int screenSize[4];
        glGetIntegerv(GL_VIEWPORT, screenSize); 
            // get the width/height of the canvas
        m_iWidth = screenSize[2];
        m_iHeight = screenSize[3];
        return ;
    }

    // Stop our animation
    g_canvas->model->animManager->Pause(true);
    g_canvas->model->animManager->Stop();
    g_canvas->model->animManager->AnimateParticles();

    // Size of our buffer to hold the pixel data
    m_iSize = m_iWidth * m_iHeight * 4; // (width*height*bytesPerPixel)	

    // Create one frame to make our optimal colour palette from.
    unsigned char *buffer = new unsigned char[m_iSize];
    gifImages = new CxImage *[m_iTotalFrames];

    for(unsigned int i = 0; i < m_iTotalFrames; i++)
    {
        lblCurFrame->SetLabel(wxString::Format(_T("Current Frame: %i"), i) );

        this->Refresh();
        this->Update();

        CxImage *newImage = new CxImage(0);

        g_canvas->RenderToBuffer();

        glReadPixels(0, 0, m_iWidth, m_iHeight, GL_BGRA_EXT, GL_UNSIGNED_BYTE,
            buffer);
        newImage->CreateFromArray(buffer, m_iWidth, m_iHeight, 32, (m_iWidth *4)
            , false);

        // not needed due to the code just below, which fixes the issue with particles
        //g_canvas->model->animManager->SetTimeDiff(m_iTimeStep);
        //g_canvas->model->animManager->Tick(m_iTimeStep);

        if(g_canvas->root)
        {
            g_canvas->root->tick( (float)m_iTimeStep);
        }
        if(g_canvas->sky)
        {
            g_canvas->sky->tick( (float)m_iTimeStep);
        }


#ifdef _WIN32
        if(m_bGreyscale)
        {
            newImage->GrayScale();
        }
#endif //_WIN32

        if(m_bShrink && m_iNewWidth != m_iWidth && m_iNewHeight != m_iHeight)
        {
            newImage->Resample(m_iNewWidth, m_iNewHeight, 2);
        }

        // if (Optimise) {
        if(!m_pPal)
        {
            CQuantizer q(256, 8);
            q.ProcessImage( (HANDLE)newImage->GetDIB() );
            m_pPal = (RGBQUAD*)calloc(256 *sizeof(RGBQUAD), 1); 
                //This creates our gifs optimised global colour palette
            q.SetColorTable(m_pPal);
        }

        newImage->DecreaseBpp(8, m_bDiffuse, m_pPal, 256);
        newImage->SetCodecOption(2); // for LZW compression

        if(m_bTransparent)
        {
            newImage->SetTransIndex(newImage->GetPixelIndex(0, 0) );
        }

        newImage->SetFrameDelay(m_iDelay);

        gifImages[i] = newImage;

        // All the memory that we allocate for newImage gets cleared at the end
    }

    wxDELETEA(buffer);

    if(g_videoSetting.supportPBO || g_videoSetting.supportVBO)
    {
        g_canvas->rt->EndRender();

        // Clear RenderTexture object.
        g_canvas->rt->Shutdown();
        wxDELETE(g_canvas->rt);
    }

    // CREATE THE ACTUAL MULTI-IMAGE GIF ANIMATION
    // ------------------------------------------------------
    // Create the file and write all the data
    // Open/Create the file that were going to save to
    FILE *hFile = NULL;
    hFile = fopen(m_strFilename.fn_str(), "wb");

    // Set gif options
    CxImageGIF multiImage;
    multiImage.SetComment("Exported from WoW Model Viewer");
    if(m_bTransparent)
    {
        multiImage.SetDisposalMethod(2);
    }
    else
    {
        multiImage.SetDisposalMethod(0);
    }

    multiImage.SetFrameDelay(m_iDelay);
    multiImage.SetCodecOption(2); // LZW
    multiImage.SetLoops(0); // Set the animation to loop indefinately.

    // Create/Compose the animated gif
    multiImage.Encode(hFile, gifImages, m_iTotalFrames, false);

    // ALL DONE, START THE CLEAN UP
    // --------------------------------------------------------
    // Close file
    fclose(hFile);

    // Free the memory used by all the images to create the GIF
    for(unsigned int i = 0; i < m_iTotalFrames; i++)
    {
        gifImages[i]->Destroy();
        wxDELETE(gifImages[i]);
    }
    wxDELETEA(gifImages);

    // Free memory used by the colour palette
    if(m_pPal)
    {
        free(m_pPal);
        m_pPal = NULL;
    }

    wxLogMessage(_T("Info: GIF Animation successfully created.") );

    g_canvas->model->animManager->SetSpeed(m_fAnimSpeed); 
        // Return the animation speed back to whatever it was previously set as
    g_canvas->model->animManager->Play();

    Show(false);

    g_videoSetting.render = true;
    g_canvas->InitView();
}