Steve Brownell
Steve Brownell

Reputation: 1320

How to use httpwebrequest to pull image from website to local file

I'm trying to use a local c# app to pull some images off a website to files on my local machine. I'm using the code listed below. I've tried both ASCII encoding and UTF8 encoding but the final file is not an correct. Does anyone see what I'm doing wrong? The url is active and correct and show the image just fine when I put the address in my browser.

    private void button1_Click(object sender, EventArgs e)
    {
        HttpWebRequest lxRequest = (HttpWebRequest)WebRequest.Create("http://www.productimageswebsite.com/images/stock_jpgs/34891.jpg");

        // returned values are returned as a stream, then read into a string
        String lsResponse = string.Empty;
        HttpWebResponse lxResponse = (HttpWebResponse)lxRequest.GetResponse();
        using (StreamReader lxResponseStream = new StreamReader(lxResponse.GetResponseStream()))
        {
            lsResponse = lxResponseStream.ReadToEnd();
            lxResponseStream.Close();
        }

        byte[] lnByte = System.Text.UTF8Encoding.UTF8.GetBytes(lsResponse);

        System.IO.FileStream lxFS = new FileStream("34891.jpg", FileMode.Create);
        lxFS.Write(lnByte, 0, lnByte.Length);
        lxFS.Close();

        MessageBox.Show("done");
    }

Upvotes: 25

Views: 53429

Answers (4)

Tarek.Mh
Tarek.Mh

Reputation: 708

You can use the following method to download an image from a web site and save it, using the Image class:

WebRequest req = WebRequest.Create(imageUrl);
WebResponse resp = req.GetResponse();
Image img = Image.FromStream(resp.GetResponseStream());
img.Save(filePath +  fileName + ".jpg");

Upvotes: 1

Learner
Learner

Reputation: 2649

A variation of the answer, using async await for async file I/O. See Async File I/O on why this is important.

Download png and write to disk using BinaryReader/Writer

string outFile = System.IO.Path.Combine(outDir, fileName);

// Download file
var request = (HttpWebRequest) WebRequest.Create(imageUrl);

using (var response = await request.GetResponseAsync()){
    using (var reader = new BinaryReader(response.GetResponseStream())) {

        // Read file 
        Byte[] bytes = async reader.ReadAllBytes();

        // Write to local folder 
        using (var fs = new FileStream(outFile, FileMode.Create)) {
            await fs.WriteAsync(bytes, 0, bytes.Length);
        }
    }
}

Read all bytes extension method

public static class Extensions {

    public static async Task<byte[]> ReadAllBytes(this BinaryReader reader)
    {
        const int bufferSize = 4096;
        using (var ms = new MemoryStream())
        {
            byte[] buffer = new byte[bufferSize];
            int count;
            while ((count = reader.Read(buffer, 0, buffer.Length)) != 0) {
                await ms.WriteAsync(buffer, 0, count);
            }
            return ms.ToArray();
        }
    }
}

Upvotes: 5

Steve Brownell
Steve Brownell

Reputation: 1320

Okay, here's the final answer. It uses a memorystream as a way to buffer the data from the reaponsestream.

    private void button1_Click(object sender, EventArgs e)
    {
        byte[] lnBuffer;
        byte[] lnFile;

        HttpWebRequest lxRequest = (HttpWebRequest)WebRequest.Create("http://www.productimageswebsite.com/images/stock_jpgs/34891.jpg");
        using (HttpWebResponse lxResponse = (HttpWebResponse)lxRequest.GetResponse())
        {
            using (BinaryReader lxBR = new BinaryReader(lxResponse.GetResponseStream()))
            {
                using (MemoryStream lxMS = new MemoryStream())
                {
                    lnBuffer = lxBR.ReadBytes(1024);
                    while (lnBuffer.Length > 0)
                    {
                        lxMS.Write(lnBuffer, 0, lnBuffer.Length);
                        lnBuffer = lxBR.ReadBytes(1024);
                    }
                    lnFile = new byte[(int)lxMS.Length];
                    lxMS.Position = 0;
                    lxMS.Read(lnFile, 0, lnFile.Length);
                }
            }
        }

        using (System.IO.FileStream lxFS = new FileStream("34891.jpg", FileMode.Create))
        {
            lxFS.Write(lnFile, 0, lnFile.Length);
        }
        MessageBox.Show("done");
    }

Upvotes: 15

Phil Rykoff
Phil Rykoff

Reputation: 12087

nice image :D

try using the following code:

you needed to use a BinaryReader, 'cause an image file is binary data and thus not encoded in UTF or ASCII

edit: using'ified

HttpWebRequest lxRequest = (HttpWebRequest)WebRequest.Create(
"http://www.productimageswebsite.com/images/stock_jpgs/34891.jpg");

// returned values are returned as a stream, then read into a string
String lsResponse = string.Empty;
using (HttpWebResponse lxResponse = (HttpWebResponse)lxRequest.GetResponse()){
   using (BinaryReader reader = new BinaryReader(lxResponse.GetResponseStream())) {
      Byte[] lnByte = reader.ReadBytes(1 * 1024 * 1024 * 10);
      using (FileStream lxFS = new FileStream("34891.jpg", FileMode.Create)) {
          lxFS.Write(lnByte, 0, lnByte.Length);
      }
   }
}
MessageBox.Show("done");

Upvotes: 35

Related Questions