Believe how to encode a GIF file, a lot of friends will, and the difficulty is how to let the gif files in motion, that is, to create animated GIF.
GIF file Encoding method
Let's briefly introduce the coding method.
1. Call the Bitmapencoder.createasync static method to instantiate the encoder, to create a GIF encoder, you can call the method, specify the GUID that represents the GIF encoder, this GUID does not have to be deliberately remembered, because access to the Bitmapencoder.gifencoderid static property is Can get.
2. Call the Setpixeldata method to set the image data for the current frame. Note that after the instance is created, the Encoder object is the first frame by default, so you can call the Setpixeldata method directly when you set the data for the first picture.
3, starting from the second frame, you need to call the Gotonextframeasync method to move backward one frame before calling the Setpixeldata method to set the data. No more calls to Gotonextframeasync after the last frame is set, because there is no content, and an exception is thrown if the call to Gotonextframeasync creates a new frame without writing the data.
4. Close the associated stream.
such as the following example:
await Bitmapencoder.createasync (Bitmapencoder.gifencoderid, outstream); ... Encoder. Setpixeldata (decoder. Bitmappixelformat, decoder. Bitmapalphamode, decoder. Pixelwidth, decoder. Pixelheight, decoder. Dpix, decoder. DPIY, data); ... if (not the last frame) { await encoder. Gotonextframeasync (); }
Set the time interval
If you want to animate gif, you have to set the delay time, which is the time interval. To be implemented by means of writing image metadata .
The metadata path that represents the time interval is:
bitmapproperties PV = encoder. Bitmapproperties; Dictionary <string , bitmaptypedvalue> props = new dictionary<string , bitmaptypedvalue> (); ... // props. ADD ( /grctlext/delay ", new bitmaptypedvalue (30 Span style= "color: #000000;" , propertytype.uint16)); await PV. Setpropertiesasync (props); // write metadata
Metadata can be manipulated using a dictionary data structure, where key is the path to the field, and value is the values of that metadata, and the metadata values are encapsulated by the Bitmaptypedvalue class. The time elapsed is instantiated by the following constructor.
Public object value, PropertyType type);
Value is the metadata, type object, compatible with various values, and the type parameter specifies the data type of the metadata, which is regulated by the PropertyType enumeration under the Windows.foundation namespace.
the value of delay is 1/100 seconds, or 0.01 seconds , and if set to 50, the interval for each frame of the animation is 50 * 10 = 500 milliseconds.
The GIF file saved after setting delay has been animated, but it will stop only once. In most cases, we want the animated GIF to be played in an infinite loop, which will set the other metadata values.
Infinite loop Playback
To have the GIF loop play, you need to specify a value of two:
The first value is/appext/application, this value is required, and is fixed, is the byte representation of the string "NETSCAPE2.0", note the byte representation, do not set the string directly, The string is converted to a byte array of 11 bytes. Netscape has a browser, I believe a lot of people know that when I was in Win 98 often use this browser, hehe, has been used to win me still in use.
the second value is/appext/data. In C + +, this value typically consists of 5 bytes, but we have no problem with 4 bytes in C # (in fact, the fifth byte is ' + ', which is null, which means the end). To achieve infinite loop playback, simply write the following byte array to/appext/data.
3 1 0 0
The first byte is 3, which indicates the number of bytes immediately following it, because the subsequent 1, 0, and 0 are 3 bytes, so it has a value of 3.
The second byte must be 1, which means that GIF animation is enabled.
The third byte represents the number of times the loop plays. 0 indicates an infinite loop, and if you want the animation to stop 5 times, set it to 5. It's usually 0, because we all like dead loops.
The fourth byte is a valid high-bit iteration statistics, I do not know why, anyway, set to 0 on the line.
In fact, if you want to let the animation infinite loop, just remember 3, 1, 0, 4 value is good, directly back down also doesn't matter, anyway very good remember.
Creating an animated GIF example
This example combines 5 JPG images into a GIF file with animated effects. To save the crap, I only post the core code that creates the GIF.
Storagefolder Photofolder =knownfolders.pictureslibrary; StorageFile NewFile=awaitPhotofolder.createfileasync ("Newfile.gif", creationcollisionoption.replaceexisting); Irandomaccessstream OutStream=awaitNewfile.openasync (Fileaccessmode.readwrite); Bitmapencoder Encoder=awaitBitmapencoder.createasync (Bitmapencoder.gifencoderid, OutStream); //Meta Data /** The value of/appext/application is fixed, for "NETSCAPE2.0", 11 bytes */appext/data set to loop playback, if the field is not set, then only play once. * The value of data is a set of bytes, because the first byte is set to 3, the second byte is set to 1 to achieve the loop play effect, * Other characters can be 0; * 3-Indicates the subsequent byte block size, followed by a 1,0,0 of three bytes, Thought 3; * 1-Indicates GIF uses animation; * 0-cycles, 0 means infinite loops*/bitmapproperties PV=Encoder. Bitmapproperties; Dictionary<string, bitmaptypedvalue> props =Newdictionary<string, bitmaptypedvalue>(); byte[] buffer = System.Text.Encoding.UTF8.GetBytes ("NETSCAPE2.0"); //This field mustProps. ADD ("/appext/application",Newbitmaptypedvalue (buffer, propertytype.uint8array)); //indicates loop playbackProps. ADD ("/appext/data",NewBitmaptypedvalue (New byte[] {3,1,0,0}, Propertytype.uint8array)); //delay represents the time interval for each frame, in 1/100 secondsProps. ADD ("/grctlext/delay",NewBitmaptypedvalue ( -, propertytype.uint16)); awaitPv. Setpropertiesasync (props);//writing meta Data for( Shorti =1; I <=5; i++) {URI Uri=NewUri ("ms-appx:///assets/"+ i.tostring () +". jpg"); StorageFile InFile=awaitStoragefile.getfilefromapplicationuriasync (URI); Irandomaccessstream instream=awaitInfile.openreadasync (); //decodingBitmapdecoder decoder =awaitBitmapdecoder.createasync (Bitmapdecoder.jpegdecoderid, instream); //Get pixel dataPixeldataprovider Pxprovider =awaitdecoder. Getpixeldataasync (); byte[] data =Pxprovider.detachpixeldata (); //CodingEncoder. Setpixeldata (decoder. Bitmappixelformat, decoder. Bitmapalphamode, decoder. Pixelwidth, decoder. Pixelheight, decoder. Dpix, decoder. DPIY, data); Instream.dispose (); if(I <5) { awaitEncoder. Gotonextframeasync (); } } awaitEncoder. Flushasync (); Outstream.dispose ();
The GIF image below is created with the example above to enjoy it together.
How is it? Are these hibiscus flowers beautiful?
Source code download For the above example: Http://files.cnblogs.com/tcjiaan/BuildGifApp.zip
All right, I'll talk to you today and we'll cook.
"WP 8.1 development" How to animate animated gif