C# 为什么这段代码将截图保存为bmp而不是gif,为什么不保存整个区域?

C# 为什么这段代码将截图保存为bmp而不是gif,为什么不保存整个区域?,c#,.net,winforms,C#,.net,Winforms,我将计时器滴答声事件设置为250ms: private void timer4_Tick(object sender, EventArgs e) { if (pictureboximagestosavecount == 72) { timer4.Enabled = false; } else { Bitmap bmp = new Bitmap(this.Width, this.Height); Rectang

我将计时器滴答声事件设置为250ms:

private void timer4_Tick(object sender, EventArgs e)
{
    if (pictureboximagestosavecount == 72)
    {
        timer4.Enabled = false;
    }
    else
    {
        Bitmap bmp = new Bitmap(this.Width, this.Height);
        Rectangle rect = new Rectangle(this.Location.X, this.Location.Y, this.Width, this.Height);
        pictureboximagestosavecount++;
        savePictureBox(pictureBox1, @"c:\temp\pboximages\" + pictureboximagestosavecount.ToString("D6") + "pbimg.gif");
        this.DrawToBitmap(bmp, rect);
        bmp.Save(@"c:\temp\pboximages\" + pictureboximagestosavecount.ToString("D6") + "form.gif");
    }
}
首先,我使用savePictureBox方法将pictureBox保存为gif。 第二,我保存表单1:

bmp.Save(@"c:\temp\pboximages\" + pictureboximagestosavecount.ToString("D6") + "form.gif");
计时器4停止后,我有一个单击事件,在该事件中,我从保存的文件创建动画gif:

private void animatedgifbutton_Click(object sender, EventArgs e)
{
    DirectoryInfo di1;
    FileInfo[] fi1;
    di1 = new DirectoryInfo(@"c:\temp\pboximages\");
    fi1 = di1.GetFiles("*form.gif");
    List<string> newImages = new List<string>();
    for (int i = 0; i < fi1.Length; i++)
    {
        newImages.Add(fi1[i].FullName);
    }
    animatedgif.MakeGIF(newImages, @"c:\temp\pboximages\animated1.gif", 6, true);
}
当我执行*.form.gif时,我在列表中只看到表单gifs文件,animatedgif.MakeGIF会抛出错误,因为它需要获取gifs文件列表,但我猜当我保存表单时,它会将其保存为位图,而不是真正的gif

如何拍摄form1的屏幕截图并将其保存为真实的gif? 当我将pictureBox1保存到硬盘时,它是GIF,没有问题

问题在于保存表单

编辑:

我现在还看到,我保存表单1截图的方式并不好,它不是保存整个表单区域,而是只保存其中的一部分。使用这种bmp和rect是不好的。 这就是我在保存表单截图时得到的结果:


换句话说,我需要在timer4 tick事件中将表单屏幕以gif文件的形式保存到硬盘中,真实的gif文件不是bmp。

它不会保存为正确的gif,因为您没有告诉它。扩展名不够,您需要将ImageFormat添加到保存调用中

它不会保存表单的整个区域,因为您没有使用正确的矩形来控制它

如果使用修改后的savePictueBox函数,这两个问题都会很简单地解决:

void saveControl(Control Ctl, string fileName)
{
    Rectangle Rect = Ctl.ClientRectangle;
    // if (Ctl is Form) Rect = Ctl.Bounds; // (*)
    using (Bitmap bmp = new Bitmap(Rect.Width, Rect.Height))
    {
        Ctl.DrawToBitmap(bmp, Rect );
        bmp.Save(fileName, System.Drawing.Imaging.ImageFormat.Gif);
    }
}
注意,这使用了ClientRectangle,也就是说,它省略了表单边框。如果要包含边框,可以取消对该行的注释*

现在你可以称之为

saveControl(pictureBox1, yourFileName);
作为

saveControl(this, yourOtherFileName);
关于动画GIF的两个注释:

因为您正在实时录制GIF,所以不要同时尝试创建动画! 我觉得很有趣。fireydude的答案确实有效,一旦你包含了WPF世界的所有参考资料。不确定如何获得最佳质量,不幸的是,到目前为止,没有对时间的控制。。
如果将其参数从PictureBox更改为Control并在表单中传递,则可以使用savePictureBox代码。它可以保存真正的gif,但不能保存动画gif。你也应该改变它的名字;——-创建动画GIF可能会有所帮助。。由于您是实时操作,我想录制帧和创建动画gif应该分开。。另外:保存调用中缺少ImageFormat.Gif参数@DJKRAZE它在窗口处于活动状态时工作。在这种情况下,表单捕获位于计时器内。你不知道窗口是否处于活动状态。为什么你不能检查以查看什么是活动控件?你可以检查类似于GetForegroundWindow的内容吗