Converted Image to Gif, Works Partially?

2019-07-31 09:44发布

问题:

I've written a short method for converting images(Image class) to a GifEncoder and finally saving that Gif to a file. However, when I go to open the resulting Gif created, it has some problems. 1) The Gif stops playing after 2 cycles in a browser. 2) When loaded through an image editor the colors seem to mix up a bit between pixels.

public void ConvertToGif( string DestinationPath , Image myImage , int myFrames ) {
    Bitmap myBitmap = new Bitmap( myImage.Width / myFrames , myImage.Height );
    GifBitmapEncoder myEncoder = new GifBitmapEncoder();

    int i = 0;
    while( i < myFrames ) {
        Graphics GrDrw = Graphics.FromImage( myBitmap );
        var DestRegion = new Rectangle( 0 , 0 , myBitmap.Width , myBitmap.Height );
        var SrceRegion = new Rectangle( myBitmap.Width * i , 0 , myBitmap.Width , myBitmap.Height );
        GrDrw.DrawImage( myImage , DestRegion , SrceRegion , GraphicsUnit.Pixel );
        BitmapSource mySource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap( myBitmap.GetHbitmap() , IntPtr.Zero , Int32Rect.Empty , BitmapSizeOptions.FromEmptyOptions() );
        myEncoder.Frames.Add( BitmapFrame.Create( mySource , mySource ) );
        GrDrw.Dispose();
        i += 1;
    }

    System.IO.FileStream myStream = new System.IO.FileStream( @DestinationPath , System.IO.FileMode.Create );
    myEncoder.Save( myStream );
}

The number of frames from an image created with ConvertToGif() also don't seem to register when running the resulting Gif through my other method, ConvertFromGif():

    public Image ConvertFromGif( Image myImage ) {
        var myDimensions = new FrameDimension( myImage.FrameDimensionsList[ 0 ] );
        var myFrames = myImage.GetFrameCount( myDimensions );
        var newImage = new Bitmap( myImage.Width * myFrames , myImage.Height );

        for( int i = 0; i < myFrames; i ++ ) {
            myImage.SelectActiveFrame( myDimensions , i );
            var DestRegion = new Rectangle( myImage.Width * i , 0 , myImage.Width , myImage.Height );
            var SrceRegion = new Rectangle( 0 , 0 , myImage.Width , myImage.Height );

            Graphics GrDrw = Graphics.FromImage( newImage );
            GrDrw.DrawImage( myImage , DestRegion , SrceRegion , GraphicsUnit.Pixel );
            GrDrw.Dispose();
        }

        return newImage;
    }

I can run any Gif through my ConvertFromGif() method, but Gifs made by my ConvertToGif() method won't work.

回答1:

I had a Look around and discovered that GifBitmapEncoder is only really meant to read GIFs so they can be displayed in WPF this class will allow you to create multi-framed GIFs however it does not provide a Metadata handler that allows you to put key frame information like cycle count, delay between frame etc. They have left the Metadata part out for 3rd parties to implement

Unfortunately we don't expose a metadata reader or writer for GIFs (animated or otherwise). In order to produce correct animated GIFs, you need to write out some metadata with timing information. Since we don't provide a GIF metadata handler, we do provide a mechanism for 3rd parties to write their own. Documentation for writing a metadata handler can be found here: http://msdn2.microsoft.com/en-us/library/ms737407.aspx as well as in this article http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnlong/html/wiccodec.asp.

Quote from: http://social.msdn.microsoft.com/Forums/en-US/6ef358a7-d1ac-4267-91d9-166024aad8ca/creating-animated-gif-files-in-wpf?forum=wpf

Gifs have some default timing information so you are getting the 2 cycles but that is all it may also differ from other browsers etc.

Also while looking online I saw other users having the same issue with colour bleed between frames.

There is two avenues for you: Use a 3rd party .Net Library that allows you to write Gifs or write you own.

From your previous question Convert a List of Images to a GIf I would suggest you use NGif - http://www.codeproject.com/Articles/11505/NGif-Animated-GIF-Encoder-for-NET

However if you want to create your own metadata writer for the GifBitmapEncoder follow the links provided on the post above for the documentation for metadata read and writers.