快速而平滑地滚动图像

3
当使用滚动条在浏览器中滚动图像时,图像会快速而平稳地滚动。另一方面,使用Graphics.DrawImage创建一个紧密的循环,每次迭代将位置的X坐标增加1 - 返回缓慢的运动。(即使在使控件DoubleBuffered后,它也有些抖动。)
如何像浏览器一样获得快速渲染?
void DoNow()
{
    Rectangle rec1 = new Rectangle(Point.Empty, panel1.BackgroundImage.Size);
    Rectangle rec2 = new Rectangle(Point.Empty, panel1.BackgroundImage.Size);

    using (Graphics g = Graphics.FromImage(panel1.BackgroundImage))
    {
        for (int i = 0; i < 100; i++)
        {
            rec2.Location = new Point(rec2.Location.X + 1, rec2.Location.Y);
            g.DrawImage(image, rec1, rec2, GraphicsUnit.Pixel);
            panel1.Refresh();
        }
    }
}

3
没有看到你的代码,就无法回答你的问题(这个问题也太笼统了)。只要实现得高效,即使是针对超大图像,快速滚动也是相当简单的。每次滚动条移动增加1像素位置很可能不是正确的方法——你需要依赖于图像可见与隐藏尺寸的比率。 - xxbbcc
1
你正在创建 Graphics 对象吗?你不应该这样做,它应该通过 Paint 事件参数提供给你。 - Anthony
为什么要使用DrawImage?而且在没有双缓冲的面板上呢?为什么不在带有AutoScroll的面板中使用PictureBox? - TaW
@xxbbcc:我非常想学习如何使一个圆形在屏幕上平滑移动。我从未见过这样的例子,而且一直在寻找。 - TaW
@TaW 如果我们定义“平稳”,那么我们可能在谈论不同的事情。 - xxbbcc
显示剩余19条评论
2个回答

0

从评论中看来,回答我的问题似乎是浏览器使用了硬件加速,而Winforms无法使用。(如果我理解有误,请随时纠正。)


由于评论者没有在几天内发布他们的答案,我正在取消删除我的答案。 - ispiro

0

最简单的解决方案是使用一个滚动条设置为自动的面板对象。将一个大小模式设置为自动的图片框作为子对象放置在其中。图片框将会扩展到您分配给它的图像的大小。由于图片框将会扩展到比面板更大,因此面板的滚动条将会出现。当您使用面板滚动图像时,它将会很平滑。

如果您仍然想要手动提供绘制,那么您正在遇到“闪烁”问题,因为Invalidate方法会自动执行背景擦除,而这在OnPaint事件期间不会执行。您需要对您正在绘制的父控件进行子类化,并覆盖OnPaintBackground事件。如下所示:

protected override void OnPaintBackground(PaintEventArgs pevent)
{
   // base.OnPaintBackground(pevent);
}

另外,请记得在OnPaint事件中执行所有绘图操作,并使用e.Graphics对象。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接