Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用dotimage调整动画gif的大小_C#_Graphics_Animated Gif_Dotimage - Fatal编程技术网

C# 使用dotimage调整动画gif的大小

C# 使用dotimage调整动画gif的大小,c#,graphics,animated-gif,dotimage,C#,Graphics,Animated Gif,Dotimage,我有一段调整动画GIF大小的代码。 如果有帮助,代码将始终将图像大小调整为较小的大小。 (目前没有必要让它们变得更大) 我正在使用Atalasoft的dotimage库及其示例代码进行实际的重采样。 该代码应该从磁盘读取动画gif,遍历帧,并将每个帧的大小调整为新的大小。 如果gif动画包含相同大小的帧,但调整具有不同大小帧的动画的大小会破坏动画(调整大小后帧之间不会正确重叠),我认为这是因为代码没有正确计算新的偏移量 我认为这行代码没有正确计算偏移量: 点=新点((int)(frame.Loc

我有一段调整动画GIF大小的代码。 如果有帮助,代码将始终将图像大小调整为较小的大小。 (目前没有必要让它们变得更大)

我正在使用Atalasoft的dotimage库及其示例代码进行实际的重采样。 该代码应该从磁盘读取动画gif,遍历帧,并将每个帧的大小调整为新的大小。 如果gif动画包含相同大小的帧,但调整具有不同大小帧的动画的大小会破坏动画(调整大小后帧之间不会正确重叠),我认为这是因为代码没有正确计算新的偏移量

我认为这行代码没有正确计算偏移量: 点=新点((int)(frame.Location.X*比率),(int)(frame.Location.Y*比率))

以下是完整的调整大小例程:

    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();
    }
static private void GenerateGifImage(FileStream FileStream,int OutputWidth,int outputhweight)
{            
//MemoryStream InputStream=新的MemoryStream();
FileStream InputStream=FileStream;
//Write(InputStream.GetBuffer(),0,(int)InputStream.Position);
//InputStream.Seek(0,SeekOrigin.Begin);
Image InputImage=Image.FromStream(InputStream,true,false);
//这将使InputImage中的基础图像对象无效,但类属性无效
//在处理对象之前仍将可访问
InputStream.Seek(0,SeekOrigin.Begin);
ImageInfo ImageInfo=RegisteredCoders.GetImageInfo(InputStream);
InputStream.Seek(0,SeekOrigin.Begin);
GifDecoder GifDecoder=新的GifDecoder();
int count=gidecoder.GetFrameCount(InputStream);
GifFrameCollection GifFrameCollection=新建GifFrameCollection();
gifFrameCollection.Height=OutputHeight;
gifFrameCollection.Width=OutputWidth;
//gifFrameCollection.Height=gifDecoder.Frames.Height;
//gifFrameCollection.Width=gifDecoder.Frames.Width;
双倍比率;
if(输入图像高度>输入图像宽度)
{
比率=(双)输出高度/(双)输入图像高度;
}
其他的
{
比率=(双)输出宽度/(双)输入图像宽度;
}
for(int i=0;i输出宽度)
{
frameWidth=输出宽度;
}
如果(帧高度>输出高度)
{
frameHeight=输出八;
}
大小=新大小(帧宽、帧高);
//只有当我们有一个可测量的维度时才调整大小
如果(size.Width>0&&size.Height>0)
{
//ResampleCommand ResampleCommand=新的ResampleCommand(矩形、大小、ResampleMethod.NearestNeighbor);
ResampleCommand ResampleCommand=新的ResampleCommand(矩形、大小、ResampleMethod.NearestNeighbor);
AtalaImage AtalaImage=resampleCommand.Apply(frame.Image).Image;
//保存映像以进行调试
//atalaImage.Save(“frame”+i.ToString()+“.gif”,ImageType.gif,null);
//frame.Image.Save(“frame orig”+i.ToString()+“.gif”,ImageType.gif,null);
//AtalaImage AtalaImage=frame.Image;
点=新点((int)(frame.Location.X*比率),(int)(frame.Location.Y*比率));
//点=新点((int)(frame.Location.X),(int)(frame.Location.Y));
添加(新的GifFrame(ataLaime、point、frame.DelayTime、frame.Intersected、frame.FrameDisposition、frame.TransparentIndex、frame.UseLocalPalette));
}
}
FileStream saveStream=newfilestream(“resized.gif”、FileMode.Create、FileAccess.Write、FileShare.Write);
gif编码器gifSave=新的gif编码器();
gifSave.Save(存储流,gifFrameCollection,null);
saveStream.Close();
}

如果使用不同的帧大小,则计算的比率值不正确。您应该计算每个帧的比率,以便您关心的行使用正确的比率。我不熟悉这个框架,所以我不能给你提供一个准确的例子;但它看起来应该与此类似:

GifFrame frame = gifDecoder.Frames[i];
double frameRatio;
if (frame.Height > frame.Width)
{
   frameRatio = (double)OutputHeight / (double)frame.Height;
}
else
{
   frameRatio = (double)OutputWidth / (double)frame.Width;
}

...

Point point = new Point((int)(frame.Location.X * frameRatio), (int)(frame.Location.Y * frameRatio));

如果使用不同的帧大小,则计算的比率值不正确。您应该计算每个帧的比率,以便您关心的行使用正确的比率。我不熟悉这个框架,所以我不能给你提供一个准确的例子;但它看起来应该与此类似:

GifFrame frame = gifDecoder.Frames[i];
double frameRatio;
if (frame.Height > frame.Width)
{
   frameRatio = (double)OutputHeight / (double)frame.Height;
}
else
{
   frameRatio = (double)OutputWidth / (double)frame.Width;
}

...

Point point = new Point((int)(frame.Location.X * frameRatio), (int)(frame.Location.Y * frameRatio));
我在Atalasoft工作

我对此进行了研究——您的代码完全正确,可以在大小不等的帧上正常工作。你计算的点是正确的

问题是,在3帧GIF中,第二帧和第三帧被精确地覆盖在第一帧之上,并使用非常复杂的透明遮罩来显示第一帧。当你的图像被重采样到一个新的尺寸时,遮罩可能不再精确——因为你正在调整大小,使宽度和高度仅相差一个像素,所以这个遮罩无法匹配

这个问题有几种解决办法

  • 将第2帧覆盖到第1帧上,然后重新采样并使用该图像
  • 执行#1,然后提取第2帧的矩形
  • 使用裁剪而不是重新采样--thi