Click here to Skip to main content
15,867,834 members
Articles / Desktop Programming / WPF
Tip/Trick

Use Bing Photo of the Day in Your Application

Rate me:
Please Sign up or sign in to vote.
4.80/5 (15 votes)
28 Oct 2015CPOL3 min read 29.8K   308   21   10
Download & use the Bing photo of the day in your application

Introduction

Image 1

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
<?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’s Richmond Park, 
    England (© 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…</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öltés...</message>
    </loadMessage>
    <previousImage>
      <text>Elozo</text>
    </previousImage>
    <nextImage>
      <text>Következo</text>
    </nextImage>
    <play>
      <text>Játék</text>
    </play>
    <pause>
      <text>Szü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.

C#
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
Hungary Hungary
Been interested in computers & electronics since I got my NES, eventually became a Computer engineer, now a Software Architect

Comments and Discussions

 
PraiseGreat job! Pin
Member 173750417-Mar-16 20:11
Member 173750417-Mar-16 20:11 
GeneralMy vote of 5 Pin
JoshYates198029-Oct-15 7:52
professionalJoshYates198029-Oct-15 7:52 
QuestionMinor tweaks Pin
Sinisa Hajnal29-Oct-15 1:11
professionalSinisa Hajnal29-Oct-15 1:11 
QuestionLooks pretty awesome! Pin
John Torjo28-Oct-15 23:45
professionalJohn Torjo28-Oct-15 23:45 
AnswerRe: Looks pretty awesome! Pin
webmaster44229-Oct-15 0:42
webmaster44229-Oct-15 0:42 
GeneralMy vote of 3 Pin
maq_rohit28-Oct-15 12:22
professionalmaq_rohit28-Oct-15 12:22 
GeneralRe: My vote of 3 Pin
webmaster44228-Oct-15 21:54
webmaster44228-Oct-15 21:54 
GeneralRe: My vote of 3 Pin
maq_rohit28-Oct-15 22:53
professionalmaq_rohit28-Oct-15 22:53 
Remove your temp files and then try to run this code , You will get that.
asthanarht

GeneralRe: My vote of 3 Pin
webmaster44229-Oct-15 0:44
webmaster44229-Oct-15 0:44 
GeneralRe: My vote of 3 Pin
maq_rohit29-Oct-15 7:30
professionalmaq_rohit29-Oct-15 7:30 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.