Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Use Bing Photo of the Day in Your Application

0.00/5 (No votes)
28 Oct 2015 1  
Download & use the Bing photo of the day in your application

Introduction

The best feature of the Bing search engine is that every day it has a nice photo as the start page background. Currently, I'm working on a larger app, that has a start screen & I thought about creating a similar design of different backgrounds every day.

Of course, this would require some sort of web service, and some work every now and then selecting the images. Basically, you would have to reinvent the wheel. Luckily, the Photo of the day can be downloaded easily.

Background

The Photo of the day information is available in several formats, provided by the Bing developers as an easy to use API. The photo data can be downloaded in XML, RSS and JSON formats. through the following links:

My implementation uses the XML data. I decided to use the XML data, because the Framework has built in Linq support for it, so parsing an XML is not much of a problem. RSS could be used also, but for that additional tweaking & bug fixing of the SyndicationFeed class would be required, because it has some problems with deserializing time information in RSS files. I wanted the code to be compact, so I decided to use the XML format.

The XML Layout

The XML root tag is images, which can contain multiple Image tags. In the request URL, if you change the n parameter from 1 to 10, then you will get the images of the last 10 days.

Each Image node has a copyright & a copyrightlink node, which hold information for the copyright text & the associated copyright link. The Image url is contained by the url node.

The Images can have hotspots. These hotspots are special areas of the image. If your mouse is over a hotspot area, then an associated tooltip text could be displayed using this information. This feature isn't required by me, so the implementation doesn't deal with this.

After the Images data, a tooltips node is displayed, which contains tooltip data for creating a slideshow of the images. This data can be used as tooltips for the play, pause, next, and previous buttons. The data is returned in the requested regions language. The requested region is specified by the mkt url parameter.

<?xml version="1.0" encoding="utf-8" ?>
<images>
  <image>
    <startdate>20151028</startdate>
    <fullstartdate>201510280000</fullstartdate>
    <enddate>20151029</enddate>
    <url>/az/hprichbg/rb/StagUK_EN-US9650313735_1366x768.jpg</url>
    <urlBase>/az/hprichbg/rb/StagUK_EN-US9650313735</urlBase>
    <copyright>A male red deer in London&rsquo;s Richmond Park, 
    England (&copy; Ian Schofield/Offset)</copyright>
    <copyrightlink>http://www.bing.com/search?
    	q=red+deer+(animal)&amp;form=hpcapt</copyrightlink>
    <drk>1</drk>
    <top>1</top>
    <bot>1</bot>
    <hotspots>
      <hotspot>
        <desc>You have a little something on your antler.</desc>
        <link>http://www.bing.com/images/search?q=red+deer+
        (Cervus+elaphus)&amp;FORM=hphot1</link>
        <query>There, you got it</query>
        <LocX>15</LocX>
        <LocY>33</LocY>
      </hotspot>
      <hotspot>
        <desc>This time of year in the European wilderness&hellip;</desc>
        <link>http://www.bing.com/videos/search?q=Red+Deer+Rut+
        Fight&amp;Form=hphot2#view=detail&
        	amp;mid=2A889A1A464E79E32F582A889A1A464E79E32F58</link>
        <query>These males put those antlers to dangerous use</query>
        <LocX>37</LocX>
        <LocY>42</LocY>
      </hotspot>
      <hotspot>
        <desc>There's no need to trek deep into the woods to see these stags.</desc>
        <link>http://www.bing.com/search?q=richmond+park+london&amp;form=hphot3</link>
        <query>This one lives in the middle of an urban center</query>
        <LocX>66</LocX>
        <LocY>33</LocY>
      </hotspot>
    </hotspots>
    <messages></messages>
  </image>
  <tooltips>
    <loadMessage>
      <message>Bet&ouml;lt&eacute;s...</message>
    </loadMessage>
    <previousImage>
      <text>Elozo</text>
    </previousImage>
    <nextImage>
      <text>K&ouml;vetkezo</text>
    </nextImage>
    <play>
      <text>J&aacute;t&eacute;k</text>
    </play>
    <pause>
      <text>Sz&uuml;net</text>
    </pause>
  </tooltips>
</images>

Using the Code

The interesting part of the code is located in the BingWallPaperClient.cs file, which implements the download functionality. The implementation uses image caching. The image & the assigned copyright information is stored in the temp directory of the user. If the temp file exists & it's not older than 24 hours, then no download is required, because the Photo of the day changes every 24 hours. The Image data can be used in both WPF & Windows Forms projects, because both subsystems support loading JPEG files.

The DownLoad function is available as synchronous & as an asynchronous method.

using System;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Xml.Linq;

namespace BingPhotoOfDayClient
{
    /// <summary>
    /// A class designed to download the bing photo of the day
    /// </summary>
    public class BingWallPaperClient
    {
        private readonly string _feed;
        private readonly string _tempfilename;
        private readonly string _tempcoppyright;
        private bool _loadcalled;

        /// <summary>
        /// Creates a new instance of the Bing photo downloader
        /// </summary>
        public BingWallPaperClient()
        {
            var tempdir = Environment.ExpandEnvironmentVariables("%temp%");
            _tempfilename = Path.Combine(tempdir, "bingphotooftheday.jpg");
            _tempcoppyright = Path.Combine(tempdir, "bingphotooftheday.txt");
            _loadcalled = false;

            //photo of the day data in xml format
            _feed = "http://www.bing.com/HPImageArchive.aspx?
            		format=xml&idx=0&n=1&mkt=en-US";
        }

        /// <summary>
        /// Downloads the photo of the day synchronously
        /// </summary>
        public void DownLoad()
        {
            bool downloadneeded = true;
            if (File.Exists(_tempfilename))
            {
                FileInfo fi = new FileInfo(_tempfilename);
                if ((DateTime.UtcNow - fi.LastWriteTimeUtc).TotalHours < 24)
                {
                    downloadneeded = false;
                }
            }

            if (File.Exists(_tempcoppyright))
            {
                CoppyRightData = File.ReadAllText(_tempcoppyright);
                downloadneeded = false;
            }
            else downloadneeded = true;

            _loadcalled = true;
            if (!downloadneeded) return;

            var document = XDocument.Load(_feed).Elements().Elements().FirstOrDefault();

            var url = (from i in document.Elements()
                       where i.Name == "url"
                       select i.Value.ToString()).FirstOrDefault();

            var imgurl = "http://www.bing.com" + url;

            var copyright = (from i in document.Elements()
                             where i.Name == "copyright"
                             select i.Value.ToString()).FirstOrDefault();
            var cplink = (from i in document.Elements()
                          where i.Name == "copyrightlink"
                          select i.Value.ToString()).FirstOrDefault();

            CoppyRightData = copyright + "\r\n" + cplink;
            File.WriteAllText(_tempcoppyright, CoppyRightData);

            using (var client = new WebClient())
            {
                client.DownloadFile(imgurl, _tempfilename);
            }
        }

        /// <summary>
        /// Asyncronous & awaitable version of the download routine
        /// </summary>
        /// <returns>An awaitable task</returns>
        public Task DownloadAsync()
        {
            return Task.Run(() =>
            {
                DownLoad();
            });
        }

        /// <summary>
        /// Gets the Photo of the day in a WPF complaint ImageSource
        /// </summary>
        public ImageSource WPFPhotoOfTheDay
        {
            get
            {
                if (!_loadcalled)
                   throw new InvalidOperationException("Call the DownLoad() method first");
                return new BitmapImage(new Uri(_tempfilename));
            }
        }
        /// <summary>
        /// Gets the Photo of the day in a Windows Forms complaint ImageSource
        /// </summary>
        public Bitmap WFPhotoOfTheDay
        {
            get
            {
                if (!_loadcalled)
                    throw new InvalidOperationException("Call the DownLoad() method first");
                return new Bitmap(_tempfilename);
            }
        }

        /// <summary>
        /// CoppyRight data information
        /// </summary>
        public string CoppyRightData
        {
            get;
            private set;
        }
    }
}

Points of Interest

History

  • 2015-10-28 Initial release

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here