首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在WPF中显示渐进式JPEG?

如何在WPF中显示渐进式JPEG?
EN

Stack Overflow用户
提问于 2011-05-14 14:33:04
回答 2查看 3.1K关注 0票数 18

如何显示从web URL加载的渐进式JPEG?我试图在WPF的图像控件中显示一个谷歌地图图像,但我想保持图像是一个渐进式JPG的优势。

如何在WPF中加载渐进式JPG?

代码语言:javascript
复制
Image imgMap;
BitmapImage mapLoader = new BitmapImage();

mapLoader.BeginInit();
mapLoader.UriSource = new Uri(URL);
mapLoader.EndInit();

imgMap.Source = mapLoader;

目前,我只是凑合着用这个。它只会在完全加载后显示图像。我想逐步地展示它。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-05-14 20:05:19

一个非常基本的示例。我确信有优化的空间,你可以从它做一个单独的类,可以处理大量的请求,但至少它是工作的,你可以根据你的需要来塑造它。还要注意的是,每次我们报告进度时,此示例都会创建一个图像,您应该避免它!每隔5%左右制作一张图片,以避免较大的开销。

Xaml:

代码语言:javascript
复制
<Window x:Class="ScrollViewerTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525"
    DataContext="{Binding RelativeSource={RelativeSource Self}}">
  <StackPanel>
    <TextBlock Text="{Binding Path=Progress, StringFormat=Progress: {0}}" />
    <Image Source="{Binding Path=Image}" />
  </StackPanel>
</Window>

代码隐藏:

代码语言:javascript
复制
public partial class MainWindow : Window, INotifyPropertyChanged
{

  #region Public Properties

  private int _progress;
  public int Progress
  {
    get { return _progress; }
    set
    {
      if (_progress != value)
      {
        _progress = value;

        if (PropertyChanged != null)
          PropertyChanged(this, new PropertyChangedEventArgs("Progress"));
      }
    }
  }

  private BitmapImage image;
  public BitmapImage Image
  {
    get { return image; }
    set
    {
      if (image != value)
      {
        image = value;
        if (PropertyChanged != null)
          PropertyChanged(this, new PropertyChangedEventArgs("Image"));
      }
    }
  }

  #endregion

  BackgroundWorker worker = new BackgroundWorker();

  public MainWindow()
  {
    InitializeComponent();

    worker.DoWork += backgroundWorker1_DoWork;
    worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
    worker.WorkerReportsProgress = true;
    worker.RunWorkerAsync(@"http://Tools.CentralShooters.co.nz/Images/ProgressiveSample1.jpg");
  }

  // This function is based on code from
  //   http://devtoolshed.com/content/c-download-file-progress-bar
  private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
  {
    // the URL to download the file from
    string sUrlToReadFileFrom = e.Argument as string;

    // first, we need to get the exact size (in bytes) of the file we are downloading
    Uri url = new Uri(sUrlToReadFileFrom);
    System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url);
    System.Net.HttpWebResponse response = (System.Net.HttpWebResponse)request.GetResponse();
    response.Close();
    // gets the size of the file in bytes
    Int64 iSize = response.ContentLength;

    // keeps track of the total bytes downloaded so we can update the progress bar
    Int64 iRunningByteTotal = 0;

    // use the webclient object to download the file
    using (System.Net.WebClient client = new System.Net.WebClient())
    {
      // open the file at the remote URL for reading
      using (System.IO.Stream streamRemote = client.OpenRead(new Uri(sUrlToReadFileFrom)))
      {
        using (Stream streamLocal = new MemoryStream((int)iSize))
        {
          // loop the stream and get the file into the byte buffer
          int iByteSize = 0;
          byte[] byteBuffer = new byte[iSize];
          while ((iByteSize = streamRemote.Read(byteBuffer, 0, byteBuffer.Length)) > 0)
          {
            // write the bytes to the file system at the file path specified
            streamLocal.Write(byteBuffer, 0, iByteSize);
            iRunningByteTotal += iByteSize;

            // calculate the progress out of a base "100"
            double dIndex = (double)(iRunningByteTotal);
            double dTotal = (double)byteBuffer.Length;
            double dProgressPercentage = (dIndex / dTotal);
            int iProgressPercentage = (int)(dProgressPercentage * 100);

            // update the progress bar, and we pass our MemoryStream, 
            //  so we can use it in the progress changed event handler
            worker.ReportProgress(iProgressPercentage, streamLocal);
          }

          // clean up the file stream
          streamLocal.Close();
        }

        // close the connection to the remote server
        streamRemote.Close();
      }
    }
  }

  void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
  {
    Dispatcher.BeginInvoke(
         System.Windows.Threading.DispatcherPriority.Normal,
         new Action(delegate()
         {
           MemoryStream stream = e.UserState as MemoryStream;

           BitmapImage bi = new BitmapImage();
           bi.BeginInit();
           bi.StreamSource = new MemoryStream(stream.ToArray());
           bi.EndInit();

           this.Progress = e.ProgressPercentage;
           this.Image = bi;
         }
       ));
  }

  public event PropertyChangedEventHandler PropertyChanged;
}
票数 12
EN

Stack Overflow用户

发布于 2011-05-26 07:02:30

这似乎是Image控件的一个缺点。也许你可以创建一个从图像继承的StreamImage,在构造函数中获取一个流,从流中读取后台的字节,计算出它是否足够了,用到目前为止读取的字节构造一个内部“模糊图像”,然后迭代地呈现这个图像,直到它拥有所有的字节。您必须理解渐进式JPEG的字节是如何发送的--我想这并不简单。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6000212

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档