我有一段代碼來調整動畫gif的大小。 如果它有助於代碼將始終將圖像調整爲較小的尺寸。 (現在沒有必要讓它們變大)使用dotimage調整動畫gif的大小
我正在使用Atalasoft的dotimage庫和它們的示例代碼來進行實際的重採樣。 代碼應該從磁盤讀取動畫gif,遍歷幀並將每個幀重新調整爲新的大小。 當gif動畫包含相同大小的幀但調整大小不同的幀的動畫時,此工作正常中斷動畫(調整後幀不會正確重疊),我認爲這是因爲代碼沒有計算新的正確偏移。
我認爲這是一行代碼,它不計算右邊的偏移量: Point point = new Point((int)(frame.Location.X * ratio),(int)(frame.Location.Y * ratio ));
下面是完整的調整大小常規:
static private void GenerateGifImage(FileStream fileStream, int OutputWidth, int OutputHeight)
{
// MemoryStream InputStream = new MemoryStream();
FileStream InputStream = fileStream;
// fileStream.Write(InputStream.GetBuffer(), 0, (int)InputStream.Position);
// InputStream.Seek(0, SeekOrigin.Begin);
Image InputImage = Image.FromStream(InputStream, true, false);
// this will invalidate the underlying image object in InputImage but the class properties
// will still accessible until the object is disposed
InputStream.Seek(0, SeekOrigin.Begin);
ImageInfo imageInfo = RegisteredDecoders.GetImageInfo(InputStream);
InputStream.Seek(0, SeekOrigin.Begin);
GifDecoder gifDecoder = new GifDecoder();
int count = gifDecoder.GetFrameCount(InputStream);
GifFrameCollection gifFrameCollection = new GifFrameCollection();
gifFrameCollection.Height = OutputHeight;
gifFrameCollection.Width = OutputWidth;
// gifFrameCollection.Height = gifDecoder.Frames.Height;
// gifFrameCollection.Width = gifDecoder.Frames.Width;
double ratio;
if (InputImage.Height > InputImage.Width)
{
ratio = (double)OutputHeight/(double)InputImage.Height;
}
else
{
ratio = (double)OutputWidth/(double)InputImage.Width;
}
for (int i = 0; i < count; i++)
{
GifFrame frame = gifDecoder.Frames[i];
Rectangle rectangle = new Rectangle(Point.Empty, frame.Image.Size);
int frameWidth = (int)(frame.Image.Width * ratio);
int frameHeight = (int)(frame.Image.Height * ratio);
// account for erratic rounding, seems illogical but has happened earlier when using floats instead of doubles
if (frameWidth > OutputWidth)
{
frameWidth = OutputWidth;
}
if (frameHeight > OutputHeight)
{
frameHeight = OutputHeight;
}
Size size = new Size(frameWidth, frameHeight);
// only resize if we have a measureable dimension
if (size.Width > 0 && size.Height > 0)
{
// ResampleCommand resampleCommand = new ResampleCommand(rectangle, size, ResampleMethod.NearestNeighbor);
ResampleCommand resampleCommand = new ResampleCommand(rectangle, size, ResampleMethod.NearestNeighbor);
AtalaImage atalaImage = resampleCommand.Apply(frame.Image).Image;
// save the image for debugging
// atalaImage.Save("frame" + i.ToString() + ".gif", ImageType.Gif, null);
// frame.Image.Save("frame-orig" + i.ToString() + ".gif", ImageType.Gif, null);
// AtalaImage atalaImage = frame.Image;
Point point = new Point((int)(frame.Location.X * ratio), (int)(frame.Location.Y * ratio));
// Point point = new Point((int)(frame.Location.X), (int)(frame.Location.Y));
gifFrameCollection.Add(new GifFrame(atalaImage, point, frame.DelayTime, frame.Interlaced, frame.FrameDisposal, frame.TransparentIndex, frame.UseLocalPalette));
}
}
FileStream saveStream = new FileStream("resized.gif", FileMode.Create, FileAccess.Write, FileShare.Write);
GifEncoder gifSave = new GifEncoder();
gifSave.Save(saveStream, gifFrameCollection, null);
saveStream.Close();
}
我明白了,我沒有考慮x和y偏移。 – Kolky
我試着重新計算每幀的比率,然後重新採樣每一幀,但結果偏移量和圖像大小跨過gif動畫的大小。在上面的代碼中,假設每幀將被調整爲OutputWidth,則計算比率 - 如果gif動畫是480 x 120並且我們必須將其大小調整爲479 x 119,那麼可能會有幀80 x 20(用xy偏移來對齊它)在這種情況下,每幀必須按比例調整大小,因此代碼是在for循環外部「全局」計算比率並應用每幀比率 –