在100毫秒内查看大型多页Tif图像 [英] View large multi page Tif images within 100 milliseconds

查看:157
本文介绍了在100毫秒内查看大型多页Tif图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用WinForms。在我的表单中,我有一个 pictureBox (设置为普通模式),下一个和上一个按钮。我想快速调整大小和加载多页TIF图像。当我转到多页TIF图像的下一页时,每次将图像绘制到 pictureBox 时,我都会遇到延迟。图像的平均速度大约需要800毫秒。 我想要在100毫秒内加载页面。

I'm using WinForms. Inside my form I have a pictureBox (set to normal mode), next and previous button. I want to resize and load Multipage TIF images quickly. When I go to the next page in the Multipage TIF image I experience a delay every time the image is drawn to the pictureBox. The average speed of the image takes about 800 milliseconds. I want the pages to load within 100 Milliseconds.

我希望处理大型TIF图像的性能快作为IrfanView。 IrfanView是一个小型图像查看应用程序。如果您下载IrfanView,您可以看到性能有多快。目前我有另一个解决方案,我使用多线程后台工作程序将TIF页面加载到一个数组然后我缩小它。这种方法最初需要一些时间,但这里的目标是不必等待。

I want the performance of processing large TIF images as fast as IrfanView. IrfanView is a small image viewing application. If you Download IrfanView you can see how fast the performance is. Currently I have another solution where I use multi-threading background worker to load the TIF pages into an array then I scale it down. This method requires some time initially, but the goal here is not having to wait.

有没有办法改善 Graphics.DrawImage .NET中大图像的性能?

Is there a way to improve Graphics.DrawImage performance for large images in .NET?


g.DrawImage(img,0,0,width,height); //此行导致延迟800毫秒,具体取决于您的计算机

g.DrawImage(img, 0, 0, width, height); //This line causes the delay " 800 milliseconds depending on your computer"




  • TIF图像的大小我使用:宽度= 16800,高度= 10800

  • 仅黑白Tif图像

  • 位深度= 1

  • 分辨率单位= 2

    • The size of TIF images i work with: Width=16800, Height=10800
    • Only Black and White Tif images
    • Bit depth = 1
    • Resolution Unit = 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:

      http://www.irfanview.com/

      测试:大型TIF下图

      http:// www .filedropper.com / largetifimage15pages_2

      Visual Studio解决方案

      http://www.filedropper.com/tifpreformancequestion_1

      推荐答案

      你的形象太大了。通常包括平滑计算的大小调整可能非常慢。

      Your image is too big. Resizing which normally includes smoothing calculation can be extremely slow.

      因此,唯一的方法是使用指针访问图像位并有选择地显示像素。

      Therefore, the only way is using pointer to access image bits and displaying pixels selectively.

      public unsafe Image ResizeImage(Bitmap img, int width, int height)
      {
          var stopwatch = Stopwatch.StartNew();
      
          var imgBits = img.LockBits(new Rectangle(Point.Empty, img.Size), ImageLockMode.ReadOnly, img.PixelFormat);
      
          Bitmap b = new Bitmap(width, height);
          var bBits = b.LockBits(new Rectangle(Point.Empty, b.Size), ImageLockMode.WriteOnly, b.PixelFormat);
      
          for (int j = 0; j < height; j++)
          {
              var imgJ = j * img.Height / height;
      
              for (int i = 0; i < width; i++)
              {
                  var imgI = i * img.Width / width;
      
                  var imgPointer = (byte*)imgBits.Scan0 + imgJ * imgBits.Stride + (imgI >> 3);
                  var mask = (byte)(0x80 >> (imgI & 0x7));
                  var imgPixel = (uint)(*imgPointer & mask);
      
                  var bPointer = (uint*)bBits.Scan0 + j * bBits.Width + i;
                  *bPointer = imgPixel > 0 ? 0x00FFFFFF : 0xFF000000;
              }
          }
      
          img.UnlockBits(imgBits);
          b.UnlockBits(bBits);
      
          stopwatch.Stop();
          Console.WriteLine("Resize to " + width + " x " + height + " within " + stopwatch.ElapsedMilliseconds + "ms");
      
          return b;
      }
      
      public void Test()
      {
          var rawImage = new Bitmap(@"Large_Tif_Image_15pages.tif");
          rawImage.SelectActiveFrame(FrameDimension.Page, 3);
      
          pictureBox1.Image = ResizeImage(rawImage, pictureBox1.Width, pictureBox1.Height);
      }
      




      在31ms内调整为525 x 345

      Resize to 525 x 345 within 31ms

      结果很重要。但是,质量当然不如1整秒计算。

      The result is significant. However, the quality is of course not as good as 1 full second calculation.

      var outputFactor = 1.5;
      var outputWidth = (int)(pictureBox1.Width * outputFactor);
      var outputHeight = (int)(pictureBox1.Height * outputFactor);
      var outputImage = ResizeImage(rawImage, outputWidth, outputHeight);
      

      要重新获得质量,请使用1.5等因素调整大小,以提供更多详细信息。

      To regain quality, resize with a factor, like 1.5, giving more details.

      速度和质量之间的平衡。

      Balance between speed and quality.

      这篇关于在100毫秒内查看大型多页Tif图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆