|
Cool
Blogless
|
|
|
|
|
dont know if this is exactly a gdi+ question, but been triing to set up a animated gif with transparecy.
1 try: setting up gif with one chosen color of background to be transparent. no solution because gif has white background and white spots in middle of the image too, i dont want both of them transparent
2 try: with image ready and photoshop, using magic wand to change background to transparent. this actualy makes transparency as i want it, but there is another problem, let say there are 2 frames and on each the object is not on the same spot so when the animation is running the frames overwritre each other and color parts of the previous frames stay on image until the frameset is ended
How can i set frames of gif image to disapear when their time is up so the next transparent frame has all the transparency it needs
thx, liq
|
|
|
|
|
if your using code similar to this example this can be accomplished by using RedrawWindow() with RDW_ERASE flag. this assumes your window your rendering on is processing the WM_ERASEBKGND message. Then render your image.
Or, you could use a version like I have implimented that instead of rendering direct to the window, the thread simply invalidates the window for the rectangle with the image and then the paint operation for the window calls a draw function in the ImageEx to do the actual rendering. In this case I found it helpful to add another event object so the thread can wait till it is told to draw before proceeding to the frame wait. This prevents the image from jumping on heavily loaded systems. However this can make the animation look jerky.
Doing transparent rendering of GIFs without using photoshop's wand, which is just registering transparent entries in the GIF's pallete isn't difficult. Just pick a color for the image to be the transparent color, probably like your doing already for bitmaps.
Use ImageAttributes class to setup for the transparency. use the SetColorKey() high == low color if your not using a range of colors that are transparent the default adjustment is normally fine.
Now instead DrawImage used in the example use one that takes ImageAttributes as a parameter. That will produce the transparent redering...
NOTE: you cannot use a COLORREF directly with the ImageAttributes. The COLOR image is hardware representations... in 32bpp I believe its the same... but 16bpp isn't... Easy way around this is to have a location that is alway transparent, and grab the pixel color using Image->GetPixel()...
if you only have a COLORREF then you must convert. I will bless you with a solution to this...
with clr == COLORREF
and img == Image *
<br />
if( PixelFormat16bppRGB555 == img->GetPixelFormat() ){<br />
return Gdiplus::Color( (GetRValue(clr) & 0xF8) | (GetRValue(clr)>>5), <br />
(GetGValue(clr) & 0xF8) | (GetGValue(clr)>>5), <br />
(GetBValue(clr) & 0xF8) | (GetBValue(clr)>>5) );<br />
}else if( PixelFormat16bppRGB565 == img->GetPixelFormat() ){<br />
return Gdiplus::Color( (GetRValue(clr) & 0xF8) | (GetRValue(clr)>>5),<br />
(GetGValue(clr) & 0xFC) | (GetGValue(clr)>>6),<br />
(GetBValue(clr) & 0xF8) | (GetBValue(clr)>>5) );<br />
}<br />
|
|
|
|
|
I solve this problem calling Graphics::Clear(), into the method ImageEx::DrawFrameGif().
When the Graphics::Clear() is called it paint the background according to color specified by parameter. So I get the COLORREF of the 3D Face dialog, using GetSysColor( COLOR_3DFACE ) and convert this value to ARGB using the method Color::SetFromCOLORREF(), than I just pass this value in the Graphics::Clear() method.
Example:
ImageEx::DrawFrameGif()
{
...
HDC hDC = GetDC(m_hWnd);
if (hDC)
{
Graphics graphics(hDC);
//////////// Modify here////////////
// clear the background with the COLOR_3DFACE color
Color color;
color.SetFromCOLORREF( GetSysColor( COLOR_3DFACE ) );
graphics.Clear(color);
////////////////////////////////////
graphics.DrawImage(this, m_pt.x, m_pt.y, hmWidth, hmHeight);
ReleaseDC(m_hWnd, hDC);
}
...
}
Claudio Sampaio
Manaus-AM Brasil
|
|
|
|
|
this way is well.but why button is don't display? how to show it?
hi how are you
|
|
|
|
|
Maybe unnecessary to clear all DC, try below:
bool ImageEx::DrawFrameGIF()
{
::WaitForSingleObject(m_hPause, INFINITE);
GUID pageGuid = FrameDimensionTime;
long hmWidth = GetWidth();
long hmHeight = GetHeight();
HDC hDC = GetDC(m_hWnd);
if (hDC)
{
CRect rc(m_pt.x, m_pt.y, m_pt.x+hmWidth, m_pt.y+hmHeight);
InvalidateRect(m_hWnd, rc, TRUE);
//UpdateWindow(m_hWnd);
Graphics graphics(hDC);
graphics.DrawImage(this, m_pt.x, m_pt.y, hmWidth, hmHeight);
ReleaseDC(m_hWnd, hDC);
}
SelectActiveFrame(&pageGuid, m_nFramePosition++);
if (m_nFramePosition == m_nFrameCount)
m_nFramePosition = 0;
long lPause = ((long*) m_pPropertyItem->value)[m_nFramePosition] * 10;
DWORD dwErr = WaitForSingleObject(m_hExitEvent, lPause);
return dwErr == WAIT_OBJECT_0;
}
|
|
|
|
|
Hey Guys,
The InvalidateRect method is bad because it flickers. The color fill method is bad because it doesn't work if you have a bitmap or image behind the transparent gif. So what you really need to do is grab what is behind the transparent gif. So here is how you do that
1. First create three member variables in ImageEx.h
<br />
HBITMAP m_hBackgroundBitmap, m_hOldBitmap;<br />
HDC m_hBackgroundDC;<br />
2. In the InitAnimation function initialize the variables to null
<br />
m_hBackgroundBitmap = NULL;<br />
m_hBackgroundDC = NULL;<br />
3. In DrawFrameGIF function insert the code as follows
<br />
CRect rc2(0,0, hmWidth, hmHeight);<br />
<br />
if(m_hBackgroundDC == NULL && m_hBackgroundBitmap == NULL)<br />
{<br />
m_hBackgroundDC = CreateCompatibleDC(hDC);<br />
m_hBackgroundBitmap = CreateCompatibleBitmap(hDC, hmWidth, hmHeight);<br />
m_hOldBitmap = (HBITMAP)SelectObject(m_hBackgroundDC, m_hBackgroundBitmap);<br />
BitBlt(m_hBackgroundDC, 0,0, hmWidth, hmHeight, hDC, m_pt.x, m_pt.y, SRCCOPY);<br />
}<br />
<br />
if (hDC)<br />
{<br />
Graphics graphics(hDC);<br />
BitBlt(hDC, m_pt.x, m_pt.y,hmWidth, hmHeight, m_hBackgroundDC, 0,0, SRCCOPY); <br />
graphics.DrawImage(this, m_pt.x, m_pt.y, hmWidth, hmHeight);<br />
ReleaseDC(m_hWnd, hDC);<br />
}<br />
4. Clean up our mess in the destroy function
<br />
void ImageEx::Destroy()<br />
{<br />
SelectObject(m_hBackgroundDC, m_hOldBitmap);<br />
DeleteDC(m_hBackgroundDC);<br />
DeleteObject(m_hBackgroundBitmap);<br />
}<br />
And there you have it. This will allow the transparent gif to display correctly over top of anything that his behind it.
Cheers,
Greg
|
|
|
|
|
Thank you, it is perfect.
But...
I have a transparent animated gif.
I show it from the program directly on the desktop.
On XP it works fine.
But on Vista the animated gif appeares in a black rect (it is not transparent).
Any idea?
Istvan
|
|
|
|
|
Hi,
First: thanks very much, nice article, which helped me very! But I've got a little problem. How can I get the Rendering Time of each frame? You know, in a GIF every frame has got a time which says how long this frame should be rendered.
sorry for my bad english, but I'd be so pleased if you could help me
regards,
Kohaku-Chan
|
|
|
|
|
|
|
I have created Gif File Like this.
Image img1("simple.gif");
Now I want to change the Color Pallete of the Gif File.
How do I change it?.please any one know about that ,send me reply immediatelly.
|
|
|
|
|
I have used this code in Visual C++ 6 just fine. I recently converted my application to Visual Studio 2003 and it does seem to know what ifstream.h is.
Anyone have a solution?
|
|
|
|
|
do you mean by not knowing it as in it cannot find it to include?
if so, then the reason is VS2003 reorganzed the headers a little. So with many VS6 projects have to have some header includes changed. Typically it just needs to be removed because its been merged with another header.
I got this code to work under VS7.1 and VS8 RC1
|
|
|
|
|
I either figured it out or found something else but thanks for the response.
|
|
|
|
|
Hi, Great examples!
I am thinking to display .gif file on the toolbar and react to user click -- something like banner ads. Can anyone let me know how to do it using Win SDK or WTL?
Thanks a lot in advance,
Sam
|
|
|
|
|
Would you tell me how to save DC as file(like jpg) use GDI+.
I don't know how to save like this.
====================================================
HDC h = ::GetDC(NULL);
HBITMAP bmp = ::CreateCompatibleBitmap(h,0,0);
HDC win = ::GetDC(m_hWnd);
Graphics g(win);
::BitBlt(win,0,0,1024,768,h,0,0,SRCCOPY);
===================================================
how to save g to file(.jpg)......thank you....
I like C.....
I can't C++
|
|
|
|
|
Hi Norm,
I need to create an animated Gif on the fly, because I need to create dynamic animations in a web page. How I can do this?
Any information about this can help me.
Thanks.
Gustavo
|
|
|
|
|
Did you ever figure this out? If so I could use a hand with the same thing
Pablo
Sometimes I think there's no reason to get out of bed . . . then I feel wet, and I realize there is.
|
|
|
|
|
when i call new ImageEX the function GdipAlloc return null??
this problem happen from my ACtiveX project but from the demo project everything is fine
any body can help??
|
|
|
|
|
I'm sure this is too late for you, since it is a year late. But anyone else with this problem the solution is you need to initialize the Gdi+.
// START GDI+ SUB SYSTEM
GdiplusStartup(&m_gdiplusToken, &m_gdiplusStartupInput, NULL);
|
|
|
|
|
Hi , nice work
I need to ask you please if it possible to strech the gif picture to a specific rectangle. That mean to a rectangle diffrent than the picture original rect.
Thanks
|
|
|
|
|
GDIPLUS! 70d06f6e()
Gdiplus::Image::~Image() line 92
ImageEx::~ImageEx() line 98 + 15 bytes
ImageEx::`scalar deleting destructor'(unsigned int 1) + 37 bytes
CTestDlgDlg::~CTestDlgDlg() line 89 + 35 bytes
CTestDlgApp::InitInstance() line 78 + 22 bytes
AfxWinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x001329a7, int 1) line 39 + 11 bytes
WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x001329a7, int 1) line 30
WinMainCRTStartup() line 330 + 54 bytes
KERNEL32! 77e687f5()
I have tried the demo, it works well. But try another gif, error
|
|
|
|
|
sorry, a little mistake;P I have made it
|
|
|
|
|
Hi!
I spend a whole day, trying to make a transparent gif moving, perhaps this saves someones time
if you add a gif with transparency, it dont repait the backgrdound so I loaded a gif with white (255,255,255)
background and used this:
<br />
<br />
bool ImageEx::DrawFrameGIF()<br />
{<br />
....<br />
imAtr.SetColorKey(Color(255,255,255),Color(255,255,255),ColorAdjustTypeBitmap);<br />
graphics.DrawImage(this,Rect(m_pt.x, m_pt.y, hmWidth, hmHeight), 0, 0, hmWidth, hmHeight,UnitPixel,&imAtr); <br />
.....<br />
}<br />
but.. this version DrawImage() always uses the first frame in the gif.
finaly, I used the systems background color, to replace the
"transparent" color of the gif...
<br />
bool ImageEx::DrawFrameGIF()<br />
{<br />
.... <br />
ImageAttributes imAtr;<br />
BYTE r=GetRValue(GetSysColor(COLOR_BTNFACE)); BYTE g=GetGValue(GetSysColor(COLOR_BTNFACE));<br />
BYTE b=GetBValue(GetSysColor(COLOR_BTNFACE));<br />
ColorMap cMap;<br />
cMap.oldColor = Color(255, 254, 254,254); <br />
cMap.newColor = Color(255, r, g, b);<br />
<br />
Bitmap memBMP(hmWidth,hmHeight);<br />
Graphics *pMemG = Graphics::FromImage(&memBMP);<br />
pMemG->DrawImage(this, 0, 0, hmWidth, hmHeight);<br />
graphics.DrawImage(&memBMP,Rect(m_pt.x, m_pt.y, hmWidth, hmHeight), 0, 0, hmWidth, hmHeight,UnitPixel,&imAtr);
with this "double buffer" aproach, you may also use
the ImageAttributes.SetColorKey() method which adds
transparency to a bitmap, but.... then some parts of
the image still dont repaint
perhaps Im just wrong, because yesterday I saw GDI+ the first time
|
|
|
|
|