|
Any possibility of sharing your optimisations?
Thanks
|
|
|
|
|
Do you know how I can play a gif in a Form?
_____________________________
...and justice for all
APe
|
|
|
|
|
|
Just FYI
This will violate LZW Patent No. 4,558,302 by Unisys.
Compuserve hold copyright on the GIF89a but the compression used for the images internaly is LZW.
Schneider
Schneider
|
|
|
|
|
I am no lawyer, but I think the patent expired few years ago...
|
|
|
|
|
It did a few YEARS ago
So png freaks put a cap on it
|
|
|
|
|
Feature request number 1 on my pet project, www.foodcandy.com after its launch six months ago was that there're no animated gifs supported on the site. I now have it working! It should go live next week. So many thanks for this code. If someone maintains an open source version I'll be glad to contribute pieces.
|
|
|
|
|
Default loop count should be -1 (don't loop), 1 means loop once (animate twice).
|
|
|
|
|
I think that forcing the GIF to crop is not very nice Here's a change to resize the GIF frames to whatever the target (or first frame) size is.
<br />
private static Image GetResizedImage(Image imgPhoto, Size ts)<br />
{<br />
<br />
int sourceWidth = imgPhoto.Width;<br />
int sourceHeight = imgPhoto.Height;<br />
int sourceX = 0;<br />
int sourceY = 0;<br />
int destX = 0;<br />
int destY = 0;<br />
<br />
float nPercent = 0;<br />
float nPercentW = 0;<br />
float nPercentH = 0;<br />
<br />
bool sourceVertical = sourceWidth < sourceHeight;<br />
bool targetVeritcal = ts.Width < ts.Height;<br />
<br />
if (sourceVertical != targetVeritcal)<br />
{<br />
int t = ts.Width;<br />
ts.Width = ts.Height;<br />
ts.Height = t;<br />
}<br />
<br />
nPercentW = ((float)ts.Width / (float)sourceWidth);<br />
nPercentH = ((float)ts.Height / (float)sourceHeight);<br />
if (nPercentH < nPercentW)<br />
{<br />
nPercent = nPercentH;<br />
destX = System.Convert.ToInt16((ts.Width -<br />
(sourceWidth * nPercent)) / 2);<br />
}<br />
else<br />
{<br />
nPercent = nPercentW;<br />
destY = System.Convert.ToInt16((ts.Height -<br />
(sourceHeight * nPercent)) / 2);<br />
}<br />
<br />
int destWidth = (int)(sourceWidth * nPercent);<br />
int destHeight = (int)(sourceHeight * nPercent);<br />
<br />
Bitmap bmPhoto = new Bitmap(ts.Width, ts.Height,<br />
PixelFormat.Format24bppRgb);<br />
bmPhoto.SetResolution(imgPhoto.HorizontalResolution,<br />
imgPhoto.VerticalResolution);<br />
<br />
Graphics grPhoto = Graphics.FromImage(bmPhoto);<br />
grPhoto.Clear(Color.White);<br />
grPhoto.InterpolationMode =<br />
InterpolationMode.HighQualityBicubic;<br />
<br />
grPhoto.DrawImage(imgPhoto,<br />
new Rectangle(destX, destY, destWidth, destHeight),<br />
new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),<br />
GraphicsUnit.Pixel);<br />
<br />
grPhoto.Dispose();<br />
return bmPhoto;<br />
}<br />
<br />
protected void GetImagePixels()<br />
{<br />
int w = image.Width;<br />
int h = image.Height;<br />
if ((w != width)<br />
|| (h != height)<br />
)<br />
{<br />
image = GetResizedImage(image, new Size(width, height));<br />
}<br />
....<br />
<br />
public bool IsTransparent()<br />
{<br />
return transparency;<br />
}<br />
<br />
public Color GetTransparency()<br />
{<br />
Color c = Color.Empty;<br />
if (transparency)<br />
{<br />
c = Color.FromArgb(0, 0, 0, 0);
}<br />
else<br />
{<br />
c = Color.FromArgb(lastBgColor);<br />
}<br />
return c;<br />
}<br />
and finally the whole resize, very simple
<br />
<br />
public static void Resize(Stream inStream, Stream outStream, int width, int height)<br />
{<br />
GifDecoder decoder = new GifDecoder();<br />
decoder.Read(inStream);<br />
<br />
AnimatedGifEncoder encoder = new AnimatedGifEncoder();<br />
encoder.SetSize(width, height);<br />
encoder.SetFrameRate(5);<br />
encoder.SetRepeat(decoder.GetLoopCount());<br />
if (decoder.IsTransparent()) encoder.SetTransparent(decoder.GetTransparency());<br />
encoder.Start(outStream);<br />
for (int i = 0; i < decoder.GetFrameCount(); i++)<br />
{<br />
encoder.SetDelay(decoder.GetDelay(i));<br />
encoder.AddFrame(decoder.GetFrame(i));<br />
}<br />
encoder.Finish();<br />
outStream.Flush();<br />
}<br />
|
|
|
|
|
Access to the path "c:\test.gif" is denied.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.UnauthorizedAccessException: Access to the path "c:\test.gif" is denied.
Line 253: String outputFilePath = "c:\\test.gif"; //Server.MapPath("NameLogoTool/test.gif");
Line 254: AnimatedGifEncoder e = new AnimatedGifEncoder();
Line 255: e.Start(outputFilePath);
Line 256: e.SetDelay(500);
Line 257: //-1:no repeat,0:always repeat
|
|
|
|
|
Would you be interested in releasing this as an open source project? I'd be happy to set it up on SourceForge, CodePlex, or Google Code. The code you've posted works well, but it would be nice to extend it:
- allow alternate quantization methode (Octree, etc.)
- include optimizations (unsafe code, image checksums, etc.)
- leverage System.Drawing
- convert to allow use of individual functions by shifting some of the class variables to method parameters
I've already made some of these changes. It would be great to get your go-ahead to release a next version. I saw that the original Java source allowed reuse for any reason, so if I don't hear back I may just start over from the original Java source.
Jon Galloway
http://weblogs.asp.net/jgalloway
|
|
|
|
|
|
Oh, your code do not works.
Well, the follow may works.
private int NextPixel()
{
if (remaining == 0)
return EOF;
--remaining;
if (curPixel <= pixAry.GetUpperBound(0))
return pixAry[curPixel++];
return EOF;
}
Day Day Up
|
|
|
|
|
The solution for the problem with LZWEncoder making the last two pixels white is replacing "private int NextPixel()" with:
<br />
<br />
<br />
private int NextPixel() <br />
{<br />
if (remaining == 0)<br />
return EOF;<br />
<br />
--remaining;<br />
<br />
byte pix = pixAry[curPixel++];<br />
<br />
return pix & 0xff;<br />
}<br />
<br />
It is just the java code in the Refs Directory --> Gif.zip ->LZWEncoder.java
I tested it,and it works well~hoho~
|
|
|
|
|
Hi! There is a bug in your programm. It makes 2 last pixels of each frame "index 255", that often makes that pixels shining.
The bug is in private int NextPixel() in LZWEncoder.cs. If you take a look you may see that 2 last pixels returned are 0xff. Fix is obvious.
Good luck!
|
|
|
|
|
Fix is the following:
private int NextPixel()
{
if (curPixel <= pixAry.GetUpperBound(0))
{
byte pix = pixAry[curPixel++];
return pix & 0xff;
}
else
return (EOF);
}
Variable remaining in the original code is unuseful and can be removed at all.
|
|
|
|
|
Any one else having the same problem I am?
The bottom right hand corner of my animated GIFs always has a white pixel. I am 100% sure the Image i'm adding as a frame doesn't have that white pixel.
Thoughts?
Thanks.
|
|
|
|
|
Great Job gOODiDEA.NET!!! This is exactly what I have been looking for!
I modified your code a bit to support returning the animated GIF as a MemoryStream object instead of a file. This is helpful on a web server where GIF graphics are generated on the fly and it's not possible to send the output to a file first.
The modified code can be downloaded here:
http://www.thinkedgesoftware.com/download/NGif_src2.zip[^]
Feel free to incorporate the changes.
|
|
|
|
|
Sorry for my english, i'm french
Can you update the link for your modified code (
http://www.thinkedgesoftware.com/download/NGif_src2.zip) ?
Now, it doesn't exist at the server
You can send it me at etr_matty AT hotmail.com
Thank you
|
|
|
|
|
hi guy,I also need it ,if you see the msg,
please send code to ssh591@hotmail.com
thank you
|
|
|
|
|
Just change FileStream to Stream. Then use MemoryStream.
Ideally this should be rewritten with StreamWriter/Reader.
|
|
|
|
|
Does this class do any sort of opitmization? EX:
- Palette optimization, where if each frame has the same palette it doesn't have to be stored for each frame, but for the global GIF instead (GIF format allows for this right?)
- Bounding boxes that define what part of the image changes from the previous frame, so a whole frame does not need to be stored if only a little piece changes (speeds up rendering, too!)
Also is it possible to set the frame delay PER FRAME using your class? The GIF format allows this, and it is something that freeware GIF animators like UnFreez lack.
For that last piece, if not I'll probably look at the code and mod it myself to do that. Probably also code the ability to extract frame delay times if it's not already in there.
The other two would be out of my league, as I don't know that much about the GIF format to code those, unfortunately.
Looking at your example a bit closer... it might take a bit of tweaking to get it to work like other .NET classes, but I think it would be well worth the effort.
|
|
|
|
|
Well I also need that badly. The size of GIF is far too heavier. Wt abo about transparancy..?
" I have found a new world but... lost the one I belong to... "
|
|
|
|
|
Yes,the size is too heavy~~
Maybe 10 times heavy than it should be~
how to minish the size?
~~china~~
|
|
|
|
|
I also think that the image size is too big!
I resized a gif to be the same size, and it got from 20Kb to 600Kb!
Is there any way to reduce the file size?
|
|
|
|