Click here to Skip to main content
11,634,568 members (75,173 online)
Click here to Skip to main content

Adding GIF-animation using GDI+

, 29 Jan 2002 335.9K 6.5K 110
Rate this:
Please Sign up or sign in to vote.
Norm demonstrates how to coerce GDI+ into displaying animated GIFs

Motive

How many of you developers are using GDI+? I reckon, not many. As a seasoned Windows C++ programmer developing for desktop applications, I've been  using the archaic GDI on regular basis. Since the release of GDI+ (see (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdicpp) I've been using GDI+ in new applications and also converting existing applications to use GDI+. There numerous compelling reasons why you should be using GDI+, here are some:

  • Successor to GDI
  • Compatible with .NET
  • Optimizes many of the capabilities of GDI
  • Supports: Gradient Brushes, Independent Path Objects, Transformations and the Matrix Object, Scalable Regions, Alpha Blending and support for multiple image formats:
    • BMP
    • GIF
    • JPEG
    • Exif
    • PNG
    • TIFF
    • ICON
    • WMF
    • EMF

During my development of Windows GUI based applications with GDI+, I've come across the need to display animated GIFs, whilst GDI+ does not support displaying animated GIFs directly, in can be done with a little coding.

Implementation

Firstly lets look at drawing a simple image using GDI+.

void CMyWnd::OnPaint()
{
	CPaintDC dc(this);
	
	Graphics graphics(&dc); // Create a GDI+ graphics object

	Image image(L"Test.Gif"); // Construct an image
	
	graphics.DrawImage(&image, 0, 0, image.GetWidth(), image.GetHeight());	
		
}

Straight away we can see the simplistic C++ interface for using GDI objects. This makes it a sure fire way for using GDI objects. There is no need for using SelectObject to select GDI objects in and out of the device context.

For those of the readers who are not familiar with the format of an animated GIF, animated GIF is actually a series of GIF frames with a delay time associated each frame, therefore each frame can have a different delay time.

My implementation of encapsulating an animated GIF functionality derives a class called from ImageEx from the GDI+ Image class. The first task is to determine whether or not a GIF is of the animated kind. The following code demonstrates this:

bool ImageEx::TestForAnimatedGIF()
{
	UINT count = 0;
	count = GetFrameDimensionsCount();
	GUID* pDimensionIDs = new GUID[count];

	// Get the list of frame dimensions from the Image object.
	GetFrameDimensionsList(pDimensionIDs, count);

	// Get the number of frames in the first dimension.
	m_nFrameCount = GetFrameCount(&pDimensionIDs[0]);

	// Assume that the image has a property item of type PropertyItemEquipMake.
	// Get the size of that property item.
	int nSize = GetPropertyItemSize(PropertyTagFrameDelay);

	// Allocate a buffer to receive the property item.
	m_pPropertyItem = (PropertyItem*) malloc(nSize);

	GetPropertyItem(PropertyTagFrameDelay, nSize, m_pPropertyItem);


	delete pDimensionIDs;

	return m_nFrameCount > 1;
}
<!-- Info Task Footer -->

m_pPropertyItem->value is actually a pointer to an array of longs, each long is a delay time which corresponds to a GIF frame. Because GetPropertyItem returns a different size depending on what property using interested in, a Size is require and its the programmer responsibility to allocate and deallocate the memory associated with GetPropertyItem. The size is determined by calling GetPropertyItemSize supplying property tag your interested in.

Once the number of frames and delay times have been retrieved from the image, a thread is created which calls to DrawFrameGIF until the object destructs. See DrawFrameGIF below:

bool ImageEx::DrawFrameGIF()
{

	::WaitForSingleObject(m_hPause, INFINITE);

	GUID pageGuid = FrameDimensionTime;

	long hmWidth = GetWidth();
	long hmHeight = GetHeight();

	HDC hDC = GetDC(m_hWnd);
	if (hDC)
	{
		Graphics graphics(hDC);
		graphics.DrawImage(this, m_rc.left, m_rc.top, 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;
}

One other interesting aspect of this class is it has the ability of loading a image directly as a resource from an executable. I usually import my GIF into a project and give it a resource type of "GIF" and then rename the resource ID from a numeric constant to a string (see the example code).

Conclusion

If you familiar with the concepts and programming of GDI, GDI+ provides some advance features and the interface almost mirrors the .NET GDI namespace. The sample apps and code include the full listings for implementing animated GIF in your code applications. For code reference just search for GDI+ within the code. One thing I haven't included in this article is starting up and shutting the GDI+ subsystem.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

NormDroid
Software Developer (Senior) Software Kinetics
United Kingdom United Kingdom



Software Kinetics
are experts in developing customised and bespoke applications and have expertise in the development of desktop, mobile and internet applications on Windows.

We specialise in:

  • User Interface Design
  • Desktop Development
  • Windows Phone Development
  • Windows Presentation Framework
  • Windows Forms
  • Windows Communication Framework
  • Windows Services
  • Network Applications
  • Database Applications
  • Web Development
  • Web Services
  • Silverlight
  • ASP.net

Visit Software Kinetics

You may also be interested in...

Comments and Discussions

 
BugA small mistake could lead to Undefined Behavior Pin
Member 112854378-Jun-15 2:50
memberMember 112854378-Jun-15 2:50 
GeneralMy vote of 3 Pin
Mahdi Nejadsahebi30-Apr-11 21:13
groupMahdi Nejadsahebi30-Apr-11 21:13 
Questionone thread per gif, more gif picture will use more thread, and that's terrible Pin
David_LoveCpp7-Oct-10 3:31
memberDavid_LoveCpp7-Oct-10 3:31 
QuestionProblem with speed for animate gif [modified] Pin
harturo12-Feb-10 11:06
memberharturo12-Feb-10 11:06 
AnswerRe: Problem with speed for animate gif Pin
Garth J Lancaster12-Feb-10 11:58
memberGarth J Lancaster12-Feb-10 11:58 
AnswerRe: Problem with speed for animate gif [modified] Pin
harturo12-Feb-10 16:36
memberharturo12-Feb-10 16:36 
Thanks Garth, for your quickly Re.

I seen this multiplier (*10) in this page "Adding GIF Animation wit GDI+" by Norm.net.

1) I think that this multiplier is because the time retrived is in hundredths of seconds and the time
   required for the timer is in milliseconds.

2) I tink that reset the timer there is a good idea for the reason that begin a new time for timer after
   killtimer is the purpose for the loop.

The problem is that most gif's are good animated for this code, normal, but just few gif´s are very faster animated and I don't know why.

I think that must other property that throw any valor as multiplier or divisor for the reason that maybe of time resolution that needed it.

Thanks.


-- Modified Monday, February 15, 2010 8:04 PM
AnswerRe: Problem with speed for animate gif: ===THANKS, DOUBT RESOLVED=== [modified] Pin
harturo16-Feb-10 21:23
memberharturo16-Feb-10 21:23 
GeneralRe: Problem with speed for animate gif: ===THANKS, DOUBT RESOLVED=== Pin
Norm .net16-Feb-10 21:35
groupNorm .net16-Feb-10 21:35 
GeneralRe: Problem with speed for animate gif: ===THANKS, for your quickly 12 min. after Re=== Pin
harturo17-Feb-10 14:22
memberharturo17-Feb-10 14:22 
GeneralRe: Problem with speed for animate gif: ===THANKS, for your quickly 12 min. after Re=== Pin
Norm .net17-Feb-10 20:36
groupNorm .net17-Feb-10 20:36 
AnswerRe: Problem with speed for animate gif Pin
kwoitek4-Nov-10 2:07
memberkwoitek4-Nov-10 2:07 
Generalmultithreaded use Pin
Anant wakode28-Oct-09 0:35
memberAnant wakode28-Oct-09 0:35 
GeneralRe: multithreaded use Pin
Norm .net28-Oct-09 1:05
groupNorm .net28-Oct-09 1:05 
GeneralMy vote of 1 Pin
Sheetal_Joshi22-Oct-09 2:20
memberSheetal_Joshi22-Oct-09 2:20 
GeneralRe: My vote of 1 Pin
Norm .net28-Oct-09 1:02
groupNorm .net28-Oct-09 1:02 
GeneralSerious Error during drawing a Multi-Frame(&gt;10) Gif file Pin
adelezy16-Sep-09 22:07
memberadelezy16-Sep-09 22:07 
GeneralAccess Violation Pin
adelezy14-Sep-09 23:12
memberadelezy14-Sep-09 23:12 
GeneralCommercial License Pin
Rafi Rainshtein21-Jul-09 22:25
memberRafi Rainshtein21-Jul-09 22:25 
GeneralRe: Commercial License Pin
Norm .net21-Jul-09 22:40
groupNorm .net21-Jul-09 22:40 
GeneralRe: Commercial License Pin
Rafi Rainshtein22-Jul-09 1:45
memberRafi Rainshtein22-Jul-09 1:45 
GeneralVC++.Net and Images Pin
minad_7865-Sep-07 3:54
memberminad_7865-Sep-07 3:54 
GeneralRe: VC++.Net and Images Pin
norm .net5-Sep-07 3:59
membernorm .net5-Sep-07 3:59 
GeneralRe: VC++.Net and Images Pin
minad_7865-Sep-07 23:40
memberminad_7865-Sep-07 23:40 
GeneralRe: VC++.Net and Images Pin
norm .net6-Sep-07 2:09
membernorm .net6-Sep-07 2:09 
GeneralCreate animated GIF Pin
Tall Dude19-Jan-07 8:58
memberTall Dude19-Jan-07 8:58 
GeneralRe: Create animated GIF Pin
norm .net25-Jan-07 22:48
membernorm .net25-Jan-07 22:48 
GeneralGDI+ function to identify moving GIF image programatically Pin
mukta_here8-Sep-06 3:31
membermukta_here8-Sep-06 3:31 
QuestionProblem with Image object in GDI+ (VC++) Pin
Dhananjayak0214-Aug-06 4:10
memberDhananjayak0214-Aug-06 4:10 
AnswerRe: Problem with Image object in GDI+ (VC++) Pin
Infro3-Sep-06 11:45
memberInfro3-Sep-06 11:45 
AnswerRe: Problem with Image object in GDI+ (VC++) Pin
ddzh22-Nov-07 22:50
memberddzh22-Nov-07 22:50 
GeneralGDI+ Buffered image Pin
darb29-Aug-06 13:47
memberdarb29-Aug-06 13:47 
GeneralRe: GDI+ Buffered image Pin
norm .net9-Aug-06 23:36
membernorm .net9-Aug-06 23:36 
GeneralMagnificent !!!!! Pin
Hiigara3-Nov-05 3:12
memberHiigara3-Nov-05 3:12 
GeneralRe: Magnificent !!!!! Pin
norm.net7-Apr-06 23:03
membernorm.net7-Apr-06 23:03 
GeneralAnimated GIFs with transparecy Pin
liqutttt13-Apr-05 8:10
sussliqutttt13-Apr-05 8:10 
GeneralRe: Animated GIFs with transparecy Pin
defrog11-Oct-05 4:45
memberdefrog11-Oct-05 4:45 
GeneralRe: Animated GIFs with transparecy Pin
Claudio Sampaio25-Apr-06 11:02
memberClaudio Sampaio25-Apr-06 11:02 
GeneralRe: Animated GIFs with transparecy Pin
game0071-Sep-06 16:30
membergame0071-Sep-06 16:30 
GeneralRe: Animated GIFs with transparecy Pin
KenDang8-Aug-07 5:02
memberKenDang8-Aug-07 5:02 
GeneralRe: Animated GIFs with transparecy (The best way for transparency!!) Pin
Greg Ellis11-Nov-08 11:19
memberGreg Ellis11-Nov-08 11:19 
QuestionRe: Animated GIFs with transparecy (The best way for transparency!!) Pin
Istvan Lengyel27-Nov-08 5:03
memberIstvan Lengyel27-Nov-08 5:03 
GeneralRendering Time of each Frame Pin
Kohaku-Chan20-Dec-04 10:36
memberKohaku-Chan20-Dec-04 10:36 
GeneralRe: Rendering Time of each Frame Pin
TDK90000016-Oct-05 22:00
memberTDK90000016-Oct-05 22:00 
QuestionHow to create a multi-frame .gif file in C#? Pin
jackyxio23-Jul-04 23:36
memberjackyxio23-Jul-04 23:36 
QuestionHow do I change the Color Palette of Gif Image Pin
pubba2-Jul-04 17:04
susspubba2-Jul-04 17:04 
GeneralAnyone tried using this with an MFC dialog application using Visual Studio 2003 Pin
smesser16-May-04 18:13
membersmesser16-May-04 18:13 
GeneralRe: Anyone tried using this with an MFC dialog application using Visual Studio 2003 Pin
defrog11-Oct-05 5:39
memberdefrog11-Oct-05 5:39 
GeneralRe: Anyone tried using this with an MFC dialog application using Visual Studio 2003 Pin
smesser11-Oct-05 15:20
membersmesser11-Oct-05 15:20 
QuestionHow to display .gif file on the toolbar and react to user click ? Pin
Jim Morgan3-May-04 8:31
sussJim Morgan3-May-04 8:31 
GeneralAbout Save DC Pin
AlvinYoung28-Mar-04 14:55
memberAlvinYoung28-Mar-04 14:55 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150728.1 | Last Updated 30 Jan 2002
Article Copyright 2002 by NormDroid
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid