6

I'm trying to crop gif images in c# without using an add-ons with drawing a rectangle on the image (and I've got it to work with normal image), but .. lets just say the output is less than optimal.. examples:

Origianl Image:
Origianl Image

Cropped Image:
Cropped Image

and here's the code that I'm using :

public override Image Crop(Rectangle f, bool isStrch, int slashwid, int slashhei)
    {
        _revert = Image;
        GifDecoder();
        widmult = Width / (double)slashwid;
        heimult = Height / (double)slashhei;
        double num = (double)f.X * widmult;
        double num2 = (double)f.Y * heimult;
        double num3 = (double)f.Width * widmult;
        double num4 = (double)f.Height * heimult;
        Rectangle srcRect = new Rectangle(isStrch ? ((int)num) : f.X, isStrch ? ((int)num2) : f.Y, isStrch ? ((int)num3) : f.Width, isStrch ? ((int)num4) : f.Height);
        CroppedFrames = new Image[Frames.Length];            
        for (int i = 0; i < Frames.Length; i++)
        {

            Bitmap image = new Bitmap(Frames[i]);
            Bitmap bitmap = new Bitmap(srcRect.Width, srcRect.Height);
            using (Graphics graphics = Graphics.FromImage(bitmap))
            {
                graphics.DrawImage(image, new Rectangle(0, 0, bitmap.Width, bitmap.Height), srcRect, GraphicsUnit.Pixel);
            }
            CroppedFrames[i] = bitmap;
        }
        GifEncoder(f.Width,f.Height);
        return Image;
    }


private void GifDecoder()
    {
        Stream bitmapStream = new FileStream(Path, FileMode.Open, FileAccess.Read, FileShare.Read);
        GifBitmapDecoder gifBitmapDecoder = new GifBitmapDecoder(bitmapStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
        Frames = new Image[gifBitmapDecoder.Frames.Count];
        for (int i = 0; i < gifBitmapDecoder.Frames.Count; i++)
        {
            Frames[i] = BitmapFromSource(gifBitmapDecoder.Frames[i]);
        }
    }

private void GifEncoder(int width,int height)
    {
        BitmapPalette palette = new BitmapPalette(BitmapImageFromImage(Image),256);

        int bytecount = (width * height) / 8;
        using (FileStream fs = new FileStream(Path + "output.gif", FileMode.Create))
        {
            GifBitmapEncoder encoder = new GifBitmapEncoder();

            for (int f = 0; f < Frames.Length; f++)
            {
                byte[] pixels = imageToByteArray(CroppedFrames[f]);

                BitmapSource image = BitmapSource.Create(width,height,96,96,System.Windows.Media.PixelFormats.Indexed8,palette,pixels,width);

                encoder.Frames.Add(BitmapFrame.Create(image));

            }
            encoder.Save(fs);
            Image = Image.FromStream(fs);
            fs.Close();

        }
    }


private byte[] imageToByteArray(Image imageIn)
    {
        MemoryStream ms = new MemoryStream();
        Bitmap aaa = new Bitmap(imageIn);
        aaa.Save(ms, ImageFormat.Png);
        return ms.ToArray();
    }

(bool isStrch, int slashwid, int slashhei) are for checking if the picturebox is smaller than the image or not to get accurate crops with the rect.

A Loli
  • 57
  • 3
  • I do not speak C#,but my best bet here is that you are missing the alpha channel. Note how the original gif has transparency but your output has no information about that. By not getting RGBA, and instead reading as RGB, you are reading random data thus looks crap. – Ander Biguri Nov 21 '18 at 11:14
  • @AnderBiguri i actually managed to get it working but, it still doesn't loop – A Loli Nov 21 '18 at 17:22
  • So... you did not manage to get it working? – Ander Biguri Nov 21 '18 at 17:33
  • at this point yes, but it still doesn't loop, anyway this isn't my question anyway so this should be closed – A Loli Nov 22 '18 at 18:38
  • @AnderBiguri gif is 8-bit paletted, not RGBA. It has no alpha. – Nyerguds Nov 28 '18 at 21:49
  • I have built up tools to work with indexed images in .net, but never with animated ones... they just don't seem to be read correctly by the framework, and will pretend to be ARGB, thereby losing their original colour palette. I haven't found an way around that. Maybe you should simply not be using the `System.Drawing` classes for them. – Nyerguds Nov 28 '18 at 21:50
  • @Nyerguds it has transparency, somehow: http://orig09.deviantart.net/81bd/f/2013/182/9/4/finn_and_jake_by_abysswolf-d6bgo83.gif – Ander Biguri Nov 28 '18 at 21:57
  • 1
    @AnderBiguri Yes. Gif format has a specific system where one colour index gets indicated as being "the transparent colour", and all pixels of that value are treated as transparent. In fact, there are more formats like that; png even supports alpha values for all of its palette indices, but [.Net is equally dumb about that format and also treats it as ARGB](https://stackoverflow.com/questions/44835726/c-sharp-loading-an-indexed-color-image-file-correctly). – Nyerguds Nov 28 '18 at 22:10
  • @Nyerguds Interesting. I though this may be the problem because in MATLAB, similar things happened. Someone answered me a working solution in MATLAB that hacks the java classes embedded with the UI to properly show that. Not sure if its of much help here, but here it goes: https://stackoverflow.com/questions/34970064/how-to-read-an-animated-gif-with-alpha-channel – Ander Biguri Nov 29 '18 at 12:02
  • @ALoli By the way... there's an error in your `GifEncoder`. An `Image` object created from a stream [will need the stream to remain open for the entire life cycle of the image object](https://msdn.microsoft.com/en-us/library/z7ha67kw(v=vs.110).aspx#Anchor_2). After the stream is closed, the image will give errors when saved, cloned or otherwise manipulated. You keep the `Image` produced there but close the stream. More info on how to get around that can be found [here](https://stackoverflow.com/a/48579791/395685). – Nyerguds Nov 29 '18 at 14:12
  • Thank you all for your help, i've been reading about the gif format and how it stores data in binary and that helped with a lot of my problems thank you all for you help, although reading and editing binaries is out of my range atm, so i guess i'll have do with what i got. (PS, i got the image to loop). – A Loli Nov 29 '18 at 14:58

0 Answers0