Reputation: 630
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
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