【发布时间】:2016-07-09 02:22:24
【问题描述】:
我正在使用 WinForms。在我的表单中,我有一个pictureBox(设置为normal mode),下一个和上一个按钮。我想快速调整和加载多页 TIF 图像。当我转到 Multipage TIF 图像的下一页时,每次将图像绘制到 pictureBox 时都会遇到延迟。图像的平均速度大约需要 800 毫秒。 我希望页面在 100 毫秒内加载。
我希望处理大型 TIF 图像的性能与 IrfanView 一样快。 IrfanView 是一个小型图像查看应用程序。如果你下载 IrfanView 你可以看到性能有多快。目前我有另一个解决方案,我使用多线程后台工作程序将 TIF 页面加载到数组中,然后将其缩小。这种方法最初需要一些时间,但这里的目标是不必等待。
有没有办法提高 .NET 中大图像的 Graphics.DrawImage 性能?
g.DrawImage(img, 0, 0, width, height); //此行会导致延迟“ 800 毫秒,具体取决于您的计算机”
- 我使用的 TIF 图像的大小:宽度=16800,高度=10800
- 仅黑白 Tif 图像
- 位深 = 1
- 分辨率单位 = 2
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Tif_Preformance_Question
{
public partial class Form1 : Form
{
int counter = -1;
int frameCount = 0;
Stopwatch s = new Stopwatch();
Image img;
Image[] images;
public Form1()
{
InitializeComponent();
}
private void btn_Open_Click(object sender, EventArgs e)
{
var s = new Stopwatch();
s.Start();
s.Stop();
this.Text = "Elapsed Time Milliseconds" + s.ElapsedMilliseconds;
img = Image.FromFile(@"C:\image\Large_Tif_Image_15pages.tif");
frameCount = img.GetFrameCount(System.Drawing.Imaging.FrameDimension.Page);
images = new Image[frameCount];
for (int i = 0; i < frameCount; i++)
{
img.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Page, i);
images[i] = (Image)img.Clone();
}
img.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Page, 0);
pictureBox1.Image = (Image)img.Clone();
}
private void btn_Next_Click(object sender, EventArgs e)
{
counter++;
if (counter >= frameCount)
{
counter = frameCount - 1;
btn_Next.Enabled = false;
}
btn_Next.Enabled = false;
LoadPage();
btn_Next.Enabled = true;
}
private void LoadPage()
{
StartWatch();
img.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Page, counter);
pictureBox1.Image = ResizeImage((Image)img.Clone(), pictureBox1.Width, pictureBox1.Height);
pictureBox1.Refresh();
Stopwatch();
}
public Image ResizeImage(Image img, int width, int height)
{
Bitmap b = new Bitmap(width, height);
using (Graphics g = Graphics.FromImage((Image)b))
{
g.DrawImage(img, 0, 0, width, height);
}
return (Image)b;
}
private void StartWatch()
{
s.Start();
}
private void Stopwatch()
{
s.Stop();
this.Text = "Elapsed Time Milliseconds: " + s.ElapsedMilliseconds;
s.Reset();
}
}
}
参考文献
IrfanView:
测试:下方的大 TIF 图像
http://www.filedropper.com/largetifimage15pages_2
Visual Studio 解决方案
【问题讨论】:
-
也许您可以在每次导航发生时缓存上一张、当前和下一张图片?
-
我的下一个猜测是使用后台工作程序创建可以缓存的调整大小图像列表..
-
感谢您的回复,我有一个类似于您提到的解决方案。这是我使用的替代解决方案:stackoverflow.com/questions/35510498/…。此解决方案使用后台工作程序加载 TIF 页面并调整它们的大小。此解决方案仅在所有页面都已加载时才快速,但这仍然需要时间。我计划在图片框中加载图像后立即查看页面。我也不想等待很长时间才能将 TIF 图像加载到图片框中。 @TaW
-
是否有任何比 .net 代码更快的本机(c++ 或 c)库,您可以调用并让它在后台线程上进行缩减/拆分?如果您不接受第 3 方解决方案,可以考虑使用 C++ 自己创建一个库,让它执行拆分比例缩小可能会给您带来您正在寻找的效率和相应的速度提升。
-
如果我可以从应用程序调用它,我愿意使用不同的库。我在看 NuGet 的 SharpDX。这看起来很有希望,但我知道如何使用它。 @伊戈尔
标签: c# .net image winforms image-resizing