Display Dynamic GIF in WPF)

Source: Internet
Author: User
Tags reading gif

 

 

Http://www.silverlightchina.net/html/study/WPF/2011/0824/9965.html

 

 

When we seek help, the most reluctant reply is: Sorry, this function has not been implemented in the current version of the product...
This problem occurs when dynamic GIF images are displayed in WPF. However, the powerful image control in WPF does not support dynamic GIF images (it can only display the first frame ). of course, we can say that the powerful animation capabilities of WPF give us reason to discard traditional GIF animations, but in some cases, If you think dynamic GIF is more appropriate (such as QQ expressions, because GIF is conducive to storage and transmission). It doesn't matter. This article will help you solve this problem.

1. Previous attempts:

 

In the actual development process, we also encountered the problem of displaying dynamic GIF images. After we found that normal image controls could not be displayed normally, we found that Web browsers could be used, and Windows
XP's "image and fax viewer" is also acceptable, but "Window
Live photo library is not allowed. therefore, we initially intended to implement webbrowsecontrol by packaging, that is, host in WPF. the browser control in net2.0 allows the browser to implement images, but the trouble is that you can right-click the context menu of the webpage. we gave up this solution. Apart from spending time shielding the unnecessary functions of context menus and browser controls, we thought browser controls were too "Heavyweight ", it seems a little cool. in addition, you may think of using the frame control in WPF, but you will also get the above results. in addition, some netizens said they could use the mediaelement control, but most of them failed, and I did not (maybe RP is not enough, haha ...)

 

2, gifbitmapdecoder

 

We found that there is a class named gifbitmapdecoder in WPF, which can break down a dynamic GIF into multiple frames and save them in a list. Each frame is a bitmapframe object, its parent class is bitmapsource, which means that we can assign each frame to the source attribute of an image control, so that we can get the image series for each GIF frame:

 

Gifbitmapdecoder decoder = New Gifbitmapdecoder (
New Uri ( "Oh.gif" , Urikind. Relative ),
Bitmapcreateoptions. preservepixelformat, bitmapcacheoption. Default );

Foreach(Bitmapframe FInDecoder. Frames)
{
Image image =NewImage ();
Image. Source = F;
This. Panel1.children. Add (image );
}

 

 

 

A series of images generated by splitting 12 frames of a GIF image:

 

 

 

 

 

But don't be happy. This is not enough to solve our problem because we don't know the time displayed for each frame (the time interval for switching between frames ), and how to process a frame after it is displayed (is it to display the next frame? Is the background color displayed? So we have to parse the GIF file in one byte to get enough information.

 

3. parse GIF

 

To parse the file, you must know the file storage structure, about the dynamic GIF file storage structure, you can refer to here: http://blog.zhongmoo.cn/post/45.html

 

For example, the method for getting the frame display time is as follows:

 

Private Int Parsegraphiccontrolextension ( Byte [] Gifdata, Int Offset)
{
Int Returnoffset = offset;
// Extension Block
Int Length = gifdata [Offset + 2];
Returnoffset = offset + Length + 2 + 1;

byte packedfield = gifdata [Offset + 3];
currentparsegifframe. disposalmethod = (packedfield & 0x1c) >>2;

// Get delaytime
IntDelay = bitconverter. touint16 (gifdata, offset + 4 );
Currentparsegifframe. delaytime = delay;
While(Gifdata [returnoffset]! = 0x00)
{
Returnoffset = returnoffset + gifdata [returnoffset] + 1;
}

Returnoffset ++;

ReturnReturnoffset;
}

 

 

 

There is not much to talk about how to parse it. You only need to understand its file structure and constantly move the read cursor and read the corresponding bytes.

 

4. Wrap it into controls

 

The best result we want is to create a GIF image control, which is similar to the image control. We only need to specify its source attribute, and then it will automatically search for the GIF file and read or download it, then parse and display.

 

Therefore, the control is divided into two parts, one of which is responsible for searching and reading GIF files from the network or downloading them to the memory stream based on the source attribute specified by the user, the other part is responsible for parsing and displaying the obtained memory stream.

 

Where is the GIF file? This is an issue that must be taken into account. Does the control user specify an absolute path, a relative path, a local file, an embedded resource file, or a file on the network. is the file still a normal static image, so it is responsible for reading the file to the memory stream?CodeThere should be code similar to the following:

 

If (Source. Trim (). toupper (). endswith ( ". GIF" ) | Forcegifanim)
{
If (! Uri. isabsoluteuri)
{

Getgifstreamfrompack (URI );
}
Else
{

StringLeftpart = URI. getleftpart (uripartial. scheme );

If (Leftpart = "Http ://" | Leftpart ="Ftp ://" | Leftpart = "File ://" )
{

Getgifstreamfromhttp (URI );
}
Else If (Leftpart = "Pack ://" )
{

Getgifstreamfrompack (URI );
}
Else
{
// Create a normal image without animation
Createnongifanimationimage ();
}
}
}
Else
{
// Create a normal image without animation
Createnongifanimationimage ();
}
}

 

 

 

After successfully reading the file, everything is easy. By parsing the data in the memory stream, we can get enough information, such as the frame list, the display time of each frame and how to process the frame after the display is complete, then we can use a timer (dispatchertimer) to process it and form an animation.

 

/**/ /// <Summary>
/// Create an image from the memory stream
/// </Summary>
Public Void Creategifanimation (memorystream)
{
Reset ();

Byte[] Gifdata = memorystream. getbuffer ();

Gifbitmapdecoder decoder =NewGifbitmapdecoder (memorystream, bitmapcreateoptions. preservepixelformat, bitmapcacheoption. Default );

Numberofframes = decoder. frames. count;

Try
{
Parsegif (gifdata );
}
Catch
{
Throw NewFileformatexception ("Unable to parse GIF file format .");
}

For ( Int I = 0; I <decoder. frames. Count; I ++)
{
Framelist [I]. Source = decoder. Frames [I];
Framelist [I]. Visibility = visibility. hidden;
Canvas. Children. Add (framelist [I]);
Canvas. setleft (framelist [I], framelist [I]. Left );
Canvas. settop (framelist [I], framelist [I]. Top );
Canvas. setzindex (framelist [I], I );
}
Canvas. Height = logicalheight;
Canvas. width = logicalwidth;

Framelist [0]. Visibility = visibility. visible;

For(IntI = 0; I <framelist. Count; I ++)
{
Console. writeline (framelist [I]. disposalmethod. tostring () +""+ Framelist [I]. Width. tostring () +""+ Framelist [I]. delaytime. tostring ());
}

If (Framelist. Count> 1)
{
If (Numberofloops =-1)
{
Numberofloops = 1;
}
Frametimer = New System. Windows. Threading. dispatchertimer ();
Frametimer. Tick + = nextframe;
Frametimer. interval = New Timespan (0, 0, 0, 0, framelist [0]. delaytime * 10 );
Frametimer. Start ();
}
}

 

 

 

OK. We can use our GIF image control like using the image control:

 

 

 

 

 

 

 

Source code download

 

 

This article from Zhou yinhui's blog, original address: http://www.cnblogs.com/zhouyinhui/archive/2007/12/23/1011555.html

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.