Click here to Skip to main content
15,867,704 members
Articles / Desktop Programming / WPF

PhotoBooth

Rate me:
Please Sign up or sign in to vote.
4.97/5 (13 votes)
25 Jun 2009CPOL2 min read 83.9K   3K   95   15
An article on how to create a kiosk application that displays photos received via BlueTooth.

Banner.png

Introduction

This article describe some very basic techniques on how to create a photo kiosk (similar to the Kodak Picture Kiosk).

Architecture

Architecture.png

PhotoBooth uses the default MainView/MainViewModel created by the MVVM Toolkit. Various "sub-views" then gets shown or hidden based on the properties on the MainViewModel!

The MainViewModel has a ObservableCollection of photos. This gets populated by the OBEX listener. We also keep track of the current selected photo (by using CollectionView)

C#
view = (ListCollectionView)CollectionViewSource.GetDefaultView(Photos); 
view.CurrentChanged += delegate 
{ 
    SelectedPhoto = (string)view.CurrentItem; 
};

Marlon has a excellent article on this technique available here. Just remember the IsSynchronizedWithCurrentItem="True".

PhotoBooth has four sub-views:

WelcomeView

WelcomeView.png

This is the "Oooo, look at me... I am so pretty" screen to get customers to use the kiosk!

PhotoBrowserView

PhotoBrowserView.png

PhotoBrowserView shows all the photos received by the kiosk. The view can also interact with the ViewModel using two commands:

  • Clear - Removes all the photos
  • Checkout - Starts the checkout procedure

This view is only visible if HasPhotos is true.

PhotoEditView

PhotoEditView.png

The PhotoEditView allows editing and sharing of photos (not implemented yet). Basic navigation commands are available on the ViewModel:

  • NextPhoto
  • PreviousPhoto
  • UnselectPhoto

This view is only visible if IsPhotoSelected is true.

CheckoutView

CheckoutView.png

Finally, the CheckoutView shows a basket-like view of all the photos you have uploaded; here, you can also select the size of the photo to be printed!

This view is only visible if BusyCheckingOut is true.

Bluetooth

Image 7

  • Bluetooth is an open wireless protocol for exchanging data over short distances from fixed and mobile devices.
  • OBEX (OBject EXchange) is a communications protocol that facilitates the exchange of binary objects between devices.

Our PhotoBooth receives photos via Bluetooth (using the OBEX protocol). We will be using the 32 Feet library from In The Hand.

Tip: If you are developing using a 64-bit OS, also do the following (thank you big red):

Change Project > PhotoBooth Properties > Build > Platform Target: x86 (it defaults to Any CPU).

Image 8

Here is the code to start the OBEX listener:

C#
private ObexListener listener; 

private void StartObexListener() 
{ 
    radio = InTheHand.Net.Bluetooth.BluetoothRadio.PrimaryRadio; 
    
    if (radio != null) 
    { 
        radio.Mode = InTheHand.Net.Bluetooth.RadioMode.Discoverable; 
        
        listener = new ObexListener(ObexTransport.Bluetooth); 
        listener.Start(); 
        
        dispatcher = Dispatcher.CurrentDispatcher; 
        System.Threading.Thread t = new System.Threading.Thread(
           new System.Threading.ThreadStart(ObexRequestHandler)); 
        t.Start(); 
    } 
} 

private void ObexRequestHandler() 
{ 
    if (radio == null) 
        return; 

    while (listener.IsListening) 
    { 
        try 
        { 
            ObexListenerContext olc = listener.GetContext(); 
            ObexListenerRequest olr = olc.Request; 
            string filename = 
              System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal) + 
               "\\" + DateTime.Now.ToString("yyMMddHHmmss") + 
               " " + Uri.UnescapeDataString(olr.RawUrl.TrimStart(new char[] { '/' })); 
            olr.WriteFile(filename); 
            dispatcher.Invoke(new Action(delegate() 
            { 
                Photos.Add(filename); 
                OnPropertyChanged("HasPhotos"); 
            })); 
        } catch (Exception ex) 
        { 
            break; 
        } 
    } 
}

Two things to notice about this code: we force our Bluetooth radio to Discoverable mode, and we store a reference to the current Dispatcher. This allows us to Invoke back to the correct thread when we receive a photo on our background thread!

Read more here.

PhotoBooth also displays the current status of the Bluetooth radios using tooltips.

BluetoothStatusOn.png

Here is the markup:

XML
<Image Source="..\Resources\Images\bluetooth_blue.png">
    <Image.ToolTip> 
        <ToolTip> 
            <StackPanel> 
                <TextBlock Text="{Binding Radio.Name}" FontWeight="Bold"/> 
                <TextBlock Text="{Binding Radio.Manufacturer, StringFormat='Manufacturer: {0}'}" /> 
                <TextBlock Text="{Binding Radio.SoftwareManufacturer, StringFormat='Software: {0}'}" /> 
                <TextBlock Text="{Binding Radio.LocalAddress, StringFormat='Address: {0}'}" /> 
                <TextBlock Text="{Binding Radio.Mode, StringFormat='Mode: {0}'}" /> 
            </StackPanel> 
        </ToolTip> 
    </Image.ToolTip> 
</Image>

And if no radio is found?

BluetoothStatusOff.png

Animations

Most kiosks have some very fancy animations to attract the attention of the customers. I unfortunately have no design skills! The only animation that I will be using is the AnimatedWrapPanel. This gives me very basic animation on each new photo received!

XML
<ListBox> 
    <ListBox.ItemsPanel> 
        <ItemsPanelTemplate> 
            <layout:AnimatedWrapPanel /> 
        </ItemsPanelTemplate> 
    </ListBox.ItemsPanel> 
</ListBox>

Read more here.

Kiosk Tips

Most kiosks are a single application system; remember to make your application run full screen and remove the border chrome.

WindowState="Maximized" 
WindowStyle="None"

Kiosks usually uses touch screens. It is very common to then hide the cursor.

Cursor="None"

And, that's it...

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
South Africa South Africa
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Generalwhy on my mobile device radio returns null Pin
Alex Theodorou1-Dec-10 0:05
Alex Theodorou1-Dec-10 0:05 
GeneralAnimatingPanelBase Pin
Jianping Yan24-Aug-09 5:27
Jianping Yan24-Aug-09 5:27 
GeneralNice, well writen, well documented and gorgeous Pin
Raul Mainardi Neto18-Jul-09 16:55
Raul Mainardi Neto18-Jul-09 16:55 
GeneralRe: Nice, well writen, well documented and gorgeous Pin
rudigrobler19-Jul-09 23:39
rudigrobler19-Jul-09 23:39 
Generalwhy listener.IsListening Pin
Huisheng Chen26-Jun-09 2:59
Huisheng Chen26-Jun-09 2:59 
General64-bit Dev Environment Pin
bbehm25-Jun-09 18:52
professionalbbehm25-Jun-09 18:52 
I am developing on 64-bit Vista and found that I had to change the target CPU settings on my Project Settings in order to use the InTheHand.Net.BlueTooth library.

In Visual Studio change to the following...
Project > PhotoBooth Properties > Build > Platform Target: x86 (it defaults to Any CPU)

Enjoy.
GeneralRe: 64-bit Dev Environment Pin
rudigrobler25-Jun-09 20:27
rudigrobler25-Jun-09 20:27 
GeneralThe force is strong Pin
Pete O'Hanlon25-Jun-09 12:20
subeditorPete O'Hanlon25-Jun-09 12:20 
GeneralRe: The force is strong Pin
rudigrobler25-Jun-09 20:28
rudigrobler25-Jun-09 20:28 
Generalafter run, it is frozen and nothing can be run Pin
Seraph_summer17-Jun-09 9:40
Seraph_summer17-Jun-09 9:40 
GeneralRe: after run, it is frozen and nothing can be run Pin
rudigrobler17-Jun-09 9:48
rudigrobler17-Jun-09 9:48 
GeneralRe: after run, it is frozen and nothing can be run Pin
Seraph_summer17-Jun-09 10:02
Seraph_summer17-Jun-09 10:02 
GeneralRe: after run, it is frozen and nothing can be run Pin
rudigrobler17-Jun-09 23:26
rudigrobler17-Jun-09 23:26 
GeneralNot bad my son Pin
Sacha Barber17-Jun-09 4:33
Sacha Barber17-Jun-09 4:33 
GeneralRe: Not bad my son Pin
rudigrobler17-Jun-09 5:46
rudigrobler17-Jun-09 5:46 

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.