I download an image from an URL asynchronously using WebRequest this way:
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; } }
and it works ok, but I would like to show the progress of the download as the browsers do, and not to show only when it finishes.
If I do
pictureBox1.Image = Image.FromStream(readState.AccumulatedResponse);
before it finishes I get an exception that the picture is not valid, even though it has some data. Is there anyway to show partial data?
JPEG has a special encoding mode called ‘Progressive JPEG’ in which data is compressed in multiple passes of progressively higher detail. Windows 7 has built-in support for this.