如何在WPF中显示渐进JPEG?

  • 回答 (2)
  • 关注 (0)
  • 查看 (17)

如何在WPF中加载一个渐进的JPG?

Image imgMap;
BitmapImage mapLoader = new BitmapImage();

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

imgMap.Source = mapLoader;

济南庆典bwa济南庆典bwa提问于
djgump回答于
已采纳

可以尝试下:

XAML:

<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>

代码:

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;
}
kilybekb产品狗回答于

这似乎是Image控件的一个缺点。也许可以创建一个从Image继承的StreamImage,在构造函数中获取一个流,从流中读取背景中的字节,计算出足够多的时间,构造一个内部“模糊图像”

扫码关注云+社区