更快地显示图片框

发布于 2024-09-16 03:15:52 字数 618 浏览 1 评论 0原文

我正在尝试将图像快速加载到图片框中并在其上绘图。我将位图分配给图片框和它显示之间有 0.13 秒的延迟。每当我执行 picturebox.refresh() 时,调用 Paint 方法之前都会延迟 0.13 - 0.15 秒。有什么办法可以摆脱这种延迟吗?

我在 Visual Studio 2010 中使用 C#。我使用 FreeImage 库加载图像。

这是我的 pictureBox_MouseMove 事件中的代码:

if (IsMouseDown || DrawLine.Checked || IsMovingBox)  
{  
  Tracing.Trace("Update Picture Box");  
  pictureBox.Refresh();  
} 

然后,当调用绘制事件时,我绘制出一条线。延迟位于两条跟踪线之间。

如果我使用 117kb 的双色调 tiff 图像,延迟为 0.13 秒。将该图像加载到内存中需要 0.04 秒。用此位图替换我的图片框位图需要 0.01 秒。

如果我使用 1125kb 的灰度 jpg 图像,延迟为 0.14 秒。将该图像加载到内存中需要 0.26 秒。用此位图替换我的图片框位图需要 0.03 秒。

I am trying to load images quickly into a picturebox and draw on them. I have a .13 second delay between the time I assign a bitmap to the picture box and when it shows up. And whenever I do a picturebox.refresh(), it is the same delay of .13 - .15 seconds before the paint method is called. Is there any way to get rid of this delay?

I am using C# in Visual Studio 2010. I load the images using FreeImage library.

Here is the code in my pictureBox_MouseMove event:

if (IsMouseDown || DrawLine.Checked || IsMovingBox)  
{  
  Tracing.Trace("Update Picture Box");  
  pictureBox.Refresh();  
} 

Then I trace out a line when my paint event is called. The delay is between the two trace lines.

If I use a bitonal tiff image at 117kb the delay is .13 seconds. To load this image into memory takes .04 seconds. To replace my picturebox bitmap with this bitmap takes .01 seconds.

If I use a gray scale jpg image at 1125kb the delay is .14 seconds. To load this image into memory takes .26 seconds. To replace my picturebox bitmap with this bitmap takes .03 seconds.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

十雾 2024-09-23 03:15:52

假设您的代码中没有其他延迟会阻止 UI 线程重新进入消息循环,以便可以调用 OnPaint() 方法:您的 Paint 事件处理程序在绘制 PictureBox 之后被调用图像。目前还不可见,PB使用双缓冲。

当必须调整图像大小以适应 PB 的客户区域时,绘制该图像的成本会很高。这在你的情况下很可能是因为你的图像非常大。它使用高质量的双三次滤镜,使调整大小的图像看起来不错。尽管结果很好,但代价相当昂贵。

为了避免这种费用,请在将图像分配给 Image 属性之前自行调整图像的大小。使其与 PB 的 ClientSize 一样大。

这本身就会产生很大的影响。接下来您可以做的是使用 32bppPArgb 像素格式创建缩放位图。这种格式比任何其他格式快大约 10 倍,因为它与大多数机器上的视频适配器匹配,因此不需要像素格式转换。

一些代码:

    private void loadImage(string path) {
        using (var srce = new Bitmap(path)) {
            var dest = new Bitmap(pictureBox1.Width, pictureBox1.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
            using (var gr = Graphics.FromImage(dest)) {
                gr.DrawImage(srce, new Rectangle(Point.Empty, dest.Size));
            }
            if (pictureBox1.Image != null) pictureBox1.Image.Dispose();
            pictureBox1.Image = dest;
        }
    }

您可能需要对此进行修改,以便图像保留其纵横比。首先按原样尝试,以确保您确实获得性能改进。

Assuming there are no other delays in your code that would prevent the UI thread from re-entering the message loop so that the OnPaint() method can be called: your Paint event handler gets called after PictureBox has drawn the Image. It isn't yet visible, PB uses double-buffering.

That image gets expensive to draw when it has to be resized to fit the PB's client area. Which is very likely in your case because your images are pretty large. It uses a high-quality bi-cubic filter to make the resized image look good. That's pretty expensive, albeit that the result is good.

To avoid that expense, resize the image yourself before assigning it to the Image property. Make it just as large as the PB's ClientSize.

That's going to make a big difference in itself. The next thing you can do is to create the scaled bitmap with the 32bppPArgb pixel format. It's the format that's about 10 times faster then any other because it matches the video adapter on most machines so no pixel format conversions are necessary.

Some code:

    private void loadImage(string path) {
        using (var srce = new Bitmap(path)) {
            var dest = new Bitmap(pictureBox1.Width, pictureBox1.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
            using (var gr = Graphics.FromImage(dest)) {
                gr.DrawImage(srce, new Rectangle(Point.Empty, dest.Size));
            }
            if (pictureBox1.Image != null) pictureBox1.Image.Dispose();
            pictureBox1.Image = dest;
        }
    }

You'll probably want to tinker with this so the image preserves its aspect ratio. Try it first as-is to make sure you do get the perf improvement.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文