Download the Astronomy Picture of the Day in C#

[Astronomy Picture of the Day]

Each day the Astronomy Picture of the Day web page does exactly what you would expect: it displays a different astronomy picture. The pictures include planets, nebulae, spacecraft, and other astronomy-related images, and the page includes an explanation of the picture.

Long ago I had written a program to download the Astronomy Picture of the Day but at some point it stopped working because of the way that site managed its security. The images had been stored with normal http URLs but now are stored with https URLs. This example shows how to download the images with the new URL format.

When the program loads, the following code executes.

// Download the Astronomy Picture of the Day.
private void Form1_Load(object sender, EventArgs e)
{
    Cursor = Cursors.WaitCursor;
    wbrApotd.Visible = false;

    const string url = "http://antwrp.gsfc.nasa.gov/apod/";
    try
    {
        // Load the web page.
        wbrApotd.Navigate(url);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message,
            "Error navigating to " + url);
    }
}

This code stores the Astronomy Picture of the Day web site URL in a variable. It then calls the form’s WebBrowser control’s Navigate method to make the control download the web page.

When the web page has finished loading, the WebBrowser fires its DocumentCompleted event and the following code executes.

// The web page has loaded. Get the APOTD image.
private void wbrApotd_DocumentCompleted(object sender,
    WebBrowserDocumentCompletedEventArgs e)
{
    HtmlDocument doc = wbrApotd.Document;
    string src = doc.Images[0].GetAttribute("src");
    Image img = GetPicture(src);
    picApotd.Image = img;

    Cursor = Cursors.Default;
    Console.WriteLine(doc.Images[0].GetAttribute("src"));
}

This code gets the loaded web page’s HtmlDocument object. It finds the document’s first Image object and uses its GetAttribute method to get the image’s src property, which is the URL where the image is located. It calls the GetPicture method to download the image from it URL and displays it in the PictureBox named picApotd.

The following code shows the GetPicture method.

// Download a file from the internet.
// Get the picture at a given URL.
private Image GetPicture(string url)
{
    try
    {
        WebClient web_client = new WebClient();

        // Use one of the following.
        //ServicePointManager.SecurityProtocol =
        //    SecurityProtocolType.Tls12;
        ServicePointManager.SecurityProtocol =
            (SecurityProtocolType)3072;

        MemoryStream image_stream =
            new MemoryStream(web_client.DownloadData(url));
        return Image.FromStream(image_stream);
    }
    catch (Exception ex)
    {
        MessageBox.Show("Error downloading picture " +
            url + '\n' + ex.Message);
        return null;
    }
}

This method creates a new WebClient. It then sets ServicePointManager.SecurityProtocol to 3072. That tells the server to use the TLS1.2 security protocol. Unfortunately that protocol isn’t part of the SecurityProtocolType enumeration in .NET Framework versions before 4.5 and this example was written in C# 2008. To work around that, the code casts the value 3072 into the SecurityProtocolType type.

If you are using a more recent version of the .NET Framework, use the commented out value Tls12.

The code then uses the client’s DownloadData method to fetch the URL target as a data stream, uses it to create an image, and returns the result.


Download Example   Follow me on Twitter   RSS feed   Donate




About RodStephens

Rod Stephens is a software consultant and author who has written more than 30 books and 250 magazine articles covering C#, Visual Basic, Visual Basic for Applications, Delphi, and Java.

This entry was posted in graphics, image processing, internet and tagged , , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *