如何使用winforms从网上下载显示下载进度的图像?

Pab*_*tyk 8 c# image httpwebrequest winforms

我使用WebRequest以这种方式异步下载URL中的图像:

public void Download(string url)
{   
  byte[] buffer = new byte[0x1000];
  WebRequest request = HttpWebRequest.Create(url);
  request.Method = "GET";
  request.ContentType = "image/gif";

  request.BeginGetResponse(result =>
  {
    WebRequest webRequest = result.AsyncState as WebRequest;

    WebResponse response = webRequest.EndGetResponse(result);
    ReadState readState = new ReadState()
    {
      Response = response.GetResponseStream(),
      AccumulatedResponse = new MemoryStream(),
      Buffer = buffer,
    };

    readState.Response.BeginRead(buffer, 0,
      readState.Buffer.Length, ReadCallback, readState);
  }, request);
}

public void ReadCallback(IAsyncResult result)
{
  ReadState readState = result.AsyncState as ReadState;
  int bytesRead = readState.Response.EndRead(result);
  if(bytesRead > 0)
  {
    readState.AccumulatedResponse.BeginWrite(readState.Buffer, 0, bytesRead, writeResult =>
    {
      readState.AccumulatedResponse.EndWrite(writeResult);
      readState.Response.BeginRead(readState.Buffer, 0, readState.Buffer.Length, ReadCallback, readState);
    }, null);
  }
  else
  {
    readState.AccumulatedResponse.Flush();
    readState.Response.Close();
    pictureBox1.Image = Image.FromStream(readState.AccumulatedResponse);
  }
}

public class ReadState
{
  public Stream Response { get; set; }
  public Stream AccumulatedResponse { get; set; }
  public byte[] Buffer { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

并且它工作正常,但我想像浏览器那样显示下载的进度,而不是仅在完成时显示.

如果我做

pictureBox1.Image = Image.FromStream(readState.AccumulatedResponse);
Run Code Online (Sandbox Code Playgroud)

在它完成之前,我得到一个例外,即图片无效,即使它有一些数据.反正有没有显示部分数据?

Ant*_*lev 5

JPEG具有一种称为"渐进式JPEG"的特殊编码模式,其中数据在逐步更高细节的多次传递中被压缩.Windows 7 内置了对此的支持.

  • 注意他在image/gif中是硬编码的,所以这可能无济于事 (2认同)
  • Windows 7也支持GIF:http://msdn.microsoft.com/en-us/library/dd408863(VS.85).aspx #_pnggifprogressivedecoding (2认同)

Ati*_*ziz 5

我想像浏览器一样显示下载进度,而不是仅在完成时显示。

您有两个选择:

  1. 使用WebClient.DownloadDataAsync。这将引发进度事件DownloadProgressChanged,并通过该事件提供数据何时可用的最终通知DownloadDataCompleted。此时,您可以将图像分配给,例如,PictureBox.

  2. 如果您要下载图像最终显示在控件中,PictureBox那么使用 可能会更容易PictureBox.LoadAsyncLoadProgressChanged这也将通过其事件以及最终LoadCompleted完成时提供进度更新。