MySqlError
MySqlError

Reputation: 630

XNA Gif Animation

I'm editing XNA Gif Animation Library because it doesn't work properly it loads gif file but with wrong colors

here its import code

public override GifAnimationContent Import(string filename, ContentImporterContext context)
    {
        GifAnimationContent content = new GifAnimationContent();
        Image source = Image.FromFile(filename);
        FrameDimension dimension = new FrameDimension(source.FrameDimensionsList[0]);
        int frameCount = source.GetFrameCount(dimension);
        content.Frames = new TextureData[frameCount];
        for (int i = 0; i < frameCount; i++)
        {
            source.SelectActiveFrame(dimension, i);
            byte[] buffer = Quantizer.Quantize(source);
            content.Frames[i].__1__SurfaceFormat = SurfaceFormat.Color;
            content.Frames[i].__2__Width = source.Width;
            content.Frames[i].__3__Height = source.Height;
            content.Frames[i].__4__Levels = 1;
            content.Frames[i].Data = buffer;
        }
        source.Dispose();
        return content;
    }

I think that problem is SurfaceFormat.Color because Gif files doesn't support anything else except indexed palette but I can't figure out what SurfaceFormat will be correct or what kind of file convertions should be done on gif image to work properly

Please help

Thanks.

Upvotes: 1

Views: 1306

Answers (1)

Bolt
Bolt

Reputation: 28

I know this is about a million years late but in case, like me, you encounter this issue at any point in time, here is what i did to fix it after some research.

The solution to this is to open the source for the quantizer to look at quantize, and the section that assigns the bytes from the pointer thing to the byte array, you can just swap the first and third bytes (bytes for the red and blue values) and that should fix it.

But since I'm here, I may as well share another thing I did that drastically speeds up the quantizing using Marshal.Copy to copy the bytes from the pointer to the byte array. I don't know if there is any downside to doing this really or a situation where this isn't desirable so if anyone knows otherwise I'd love to hear it.

So just change

        BitmapData bitmapdata = image.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
        byte* numPtr = (byte*)bitmapdata.Scan0.ToPointer();
        int index = 0;
        byte[] buffer = new byte[(source.Width * source.Height) * 4];
        for(int i = 0; i < source.Width; i++) {
            for(int j = 0; j < source.Height; j++) {
                buffer[index] = numPtr[index];
                index++;
                buffer[index] = numPtr[index];
                index++;
                buffer[index] = numPtr[index];
                index++;
                buffer[index] = numPtr[index];
                index++;
            }
        }
        image.UnlockBits(bitmapdata);
        return buffer;

to

        BitmapData bitmapdata = copy.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
        byte[] bytes = new byte[source.Width * source.Height * 4];

        //copy the bytes from the Scan0 pointer to our byte array
        Marshal.Copy(bitmapdata.Scan0, bytes, 0, bytes.Length);

        //swap the red and blue bytes
        for(int a = 0; a < bytes.Length; a += 4) {
            byte tmp = bytes[a];
            bytes[a] = bytes[a + 2];
            bytes[a + 2] = tmp;
        }

        copy.UnlockBits(bitmapdata);

        return bytes;

this solution works great and is faster than the original code which is important if you're trying to use it in real-time like I was. To further speed it up I removed the bit where it redrew the image into a separate bitmap because I don't know why it did that to begin with and I didn't see it necessary but I could be wrong.

Also I don't know if there's a faster way to swap the red and blue bytes, I'd love to hear if there's a better way to do that too. If anyone ever reads this anyways...

Upvotes: 1

Related Questions