Tag Archives: Silverlight

How good is your Memory? Part III

In my last couple posts, I went over logging a user into Facebook via Facebook Connect, getting that user’s information and then grabbing some of the profile pictures for their friends. All of this was quite simple and brought to you by the Silverlight Facebook SDK. This post will grow more on the first post and will show you how to publish to the user’s Wall and News Feed as well as update their status.

Tell the World

One of the key things that any Facebook application should do is publish messages to the user’s stream on their Wall and News Feed. This helps spread the word that people are actually using your application as well as showing scores and updates for that user and giving some insight into why people should use your app. The first part of this equation revolves around the privacy settings that Facebook has in place. Since we are going to be doing more than just getting information, we will need the user of our application to grant extended permissions to us.

There are a couple of ways to do this, but the easiest one requires us to just add some javascript. We haven’t had to do anything to our javascript files yet, but I assure you this will be quick and painless. In your application, locate the fblogin.js file. This is usually located in the root of your web project, but in my examples has been put in a scripts folder that located at the root of the site. Once you crack that bad boy open, locate the facebook_init method. Inside this method there will be a FB.init method call which is part of the Facebook Javascript Client Library. Update this method as follows:

// original method callFB.init(appid, "/xd_receiver.htm");// updated method callFB.init(appid, "/xd_receiver.htm", {    permsToRequestOnConnect: "publish_stream"});

The change we are making is to add in a comma seperated list as a parameter to our FB.init method that tells Facebook what extra permission(s) we want the user to authorize. In this example, we are just passing in publish_stream which will allow us to publish the user’s news stream and wall as well as update their status. A complete list of the extra permission that you can request are here. Also, once the user has authorized your application, they won’t be asked again unless they remove the setting in their profile.

News Feed

So once the user has given us permission, we use the Facebook.Rest.Api.Stream.PublishAsync method call to publish to the user’s stream. When doing this, we have a couple of options. We can go the boring route of just putting up a message, or we can get fancy and add in things like links, images, and videos. The simple call looks something like this:

_facebookApi.Stream.PublishAsync(message, StreamPublishCompleted, null);

where message is just a string that we pass in the for the message the we would like to post. To add in attachments and a littler more detail, some more work is involved:

// create new attachmentattachment a = new attachment();a.name = "This is a Test";a.caption = "This is cool";a.href = "http://www.evanjohnston.com";a.description = "Here is a description that goes with this post. Here is more content to make this longer.";// create new attachment mediaattachment_media_image i = new attachment_media_image();i.href = "http://www.evanjohnston.com";i.src = "http://www.evanjohnston.com/misc/cheerssmaller.jpg";i.type = attachment_media_type.image;// create new list of attachment mediaList media = new List();media.Add(i);// add the media to the attachmenta.media = media;// this could be the id of a user to post the message tostring targetId = string.Empty;// create message stringstring message = "Testing publishing to the stream from the Silverlight Facebook SDK.";// make the api call_facebookApi.Stream.PublishAsync(message, a, new List(), targetId, 0, StreamPublishCompleted, null);

Since there is quite a bit going on here, I’ll just defer to the Facebook Wiki on this topic for a more thorough explanation. The gist of what is happening is that we are creating an attachment for the message and then adding an image to this attachment so that there is more to publish than just text.

Status Update

To show another example of what we can do once the user has give our application extended permissions, we will go ahead and update their current status as well. To do this we go with the Facebook.Rest.Api.Status.SetAsync method call. This call is straightforward and looks like this:

_facebookApi.Status.SetAsync(status, SetStatusCompleted, null);

where the status variable is a string that contains the text we want to use. It’s just that simple.

Conclusion

So in this post we expanded on our last foray into the Facebook SDK and were able to show what is required to actually publish information to the user’s status and news feed. Hope you enjoyed this brief look at the Silverlight Facebook SDK.

Code!

Here is a download of a small demo application that uses the steps that were just discussed. In order to run the application, you will need to set up your own Facebook application. Until next time, Sláinte!

Download

How good is your Memory? Part II

In my last post, I showed how easy it was to have the user log in to their Facebook account via Facebook Connect using the Facebook SDK for Silverlight and to then retrieve that user’s information. This post will take the working parts from Part I and expand on it by showing how to get the user’s list of friends and then grabbing the latest profile picture for those friends. I also hope to have a full working version of the game up by early next week that will be available on Facebook. I will post a link here when it’s available.

How Popular are You?

So in the last post, we got our logged in user, now let’s go find all their Facebook friends. To accomplish this, we will call the Facebook.Rest.Api.Friends.GetAsync method and we will pass in the uid of our user as well as a callback method that will handle the return from the api.

// here is the code for this method call_facebookApi.Friends.GetAsync((long)_currentUser.uid, GetFriendsCompleted, null);

Once we have the list of friends, we go out and use the Facebook.Rest.Api.Photos.GetAlbumsAsync method to retrieve all of the photo albums for each friend. For this demo, we will just grab the photo albums of the first twenty friends, in case they’re really popular. The GetAlbumsAsync methods takes in the uid for the friend we want to use and a callback method.

void GetFriendsCompleted(IList uids, object state, FacebookException e){    if (e == null)    {        Dispatcher.BeginInvoke(() =>        {            this.txtStatus.Text = "Loading Photos...";            // get the albums for our first 20 friends            for (int x = 0; x <; 20; x++)            {                _facebookApi.Photos.GetAlbumsAsync(uids[x], GetAlbumsCompleted, uids[x]);            }        });    }    else    {        Dispatcher.BeginInvoke(() => MessageBox.Show("Error getting friends: " + e.Message));    }}

So now that we have our list of photo albums, we need to get the pictures in each album. With the albums retrieved, the first album in the list is usually the Profile Photos. To do this, we will use the Facebook.Rest.Api.Photos.GetAsyc method. We’ll pass in an empty string for the subj_id, album id at index 0, new string array for the list of photo ids, and a callback method.

void GetAlbumsCompleted(IList albums, object state, FacebookException e){    if (e == null)    {        Dispatcher.BeginInvoke(() =>        {            if (albums.Count > 0)            {                // get the photos from the first album, which is usually the profile pictures                _facebookApi.Photos.GetAsync(string.Empty, albums[0].aid, new List(), GetPhotosCompleted, state);            }        });    }    else    {        Dispatcher.BeginInvoke(() => MessageBox.Show("Error getting albums: " + e.Message));    }}

Finally, this last callback will handle the photo’s that were returned from each query. The person’s most recent profile photo is located at index 0. To display these photos, we will create a new Image and then add it to a user control that was created to display the photos.

void GetPhotosCompleted(IList photos, object state, FacebookException e){    if (e == null)    {        Dispatcher.BeginInvoke(() =>        {            // create a new image            Image i = new Image();            i.Source = new BitmapImage(new Uri(photos[0].src));            i.Width = 140;            i.Height = 140;            i.Stretch = Stretch.Uniform;            i.Margin = new Thickness(0, 0, 5, 0);            // add the image to our user control            this.ucPhotoAlbum.AddPhoto(i);        });    }    else    {        Dispatcher.BeginInvoke(() => MessageBox.Show("Error: " + e.Message));    }}

Conclusion

So in this post we expanded on our last foray into the Facebook SDK and were able to retrieve the user’s list of friends and then get the latest profile picture for those friends. Hope you enjoyed this brief look at the Silverlight Facebook SDK.

Code!

Here is a download of a small demo application that uses the steps that were just discussed. In order to run the application, you will need to set up your own Facebook application. Until next time, Sláinte!

Download

How good is your Memory? Part I

A couple of months ago, The Silverlight Blog announced the Facebook SDK for Silverlight. I have been wanting to get a post up about using this SDK, but it has taken a while. Anyway, this is part one in what will be a three part series of a basic overview of using a little bit of what the Facebook SDK has available.

The Premise

Gathering profile and friend list information is made quite simple in the SDK, so I thought that an easy demo application would be an implementation of the childhood game Memory. However there will be a slight twist. Instead of using the same picture to match, the game will randomly select two profile pictures from your friends and use those for you to determine the match. I will post a link to a demo of the application once there’s a full working version.

Making the connection

The first step in getting this game started was being able to get the data from Facebook, and this is done using Facebook Connect. The SDK makes this very simple. Using the Facebook.Session.BrowserSession object, you simply create a new instance of a browser session with your Facebook application key, add a login completed event handler, and call BrowserSession.Login. This will open up a popup window with the Facebook connect login.

BrowserSession _browserSession;_browserSession = new BrowserSession(APPLICATION_KEY);_browserSession.LoginCompleted += LoginCompleted;_browserSession.Login();

Getting the Information

Now that the user had logged in to their Facebook account, we can go ahead and get the user id of the logged in user. First we create a new instance of the Facebook.Rest.Api class and pass in the new browser session that was just created. The method call used is Users.GetLoggedInUserAsync and we will pass in a callback for when the operation is complete and any sate we wish to pass along in an object. In this case we will just pass null.

// we use a private member variable so that it can be re-usedprivate Api _facebookApi;// create the new api instance and call the GetLoggedInUserAsync method_facebookApi = new Api(_browserSession);_facebookApi.Users.GetLoggedInUserAsync(GetLoggedInUserCompleted, null);

Next we need to handle the callback from the GetLoggedInUserAsync call. The callback method takes in a long parameter for the Facebook user id, an object for any state that you want to pass along, and any FacebookExceptions that may have occurred. Once the user id has been returned, we will make another call to the Facebook.Rest.Api class to get the user’s information. This method is Users.GetInfoAsync where we will pass in the returned user id and a callback method. We will again use null for the state parameter.

void GetLoggedInUserCompleted(long userId, object state, FacebookException e){    // check that no errors have occurred    if (e == null)    {        _facebookApi.Users.GetInfoAsync(userId, GetUserInfoCompleted, null);    }    else    {        // if any errors occurred, invoke a call back to the UI thread and show the error message        Dispatcher.BeginInvoke(() => MessageBox.Show("Error getting logged in user:nn" + e.InnerException.Message));    }}

Now that we have the current users information, we can get the information we want to pull from their profile. For this demo we will just use their name and a small version of their current profile picture. We will also set a _currentUser object that stores the user’s information that we will use later in the application

void GetUserInfoCompleted(IList<user> userDetails, object state, FacebookException e){    if (e == null)    {        Dispatcher.BeginInvoke(() =>        {            // set our user object            this._currentUser = userDetails[0];            // set user information data context            this.ucUserInformation.DataContext = _currentUser.current_location;        });     }     else     {        // if any errors occurred, invoke a call back to the UI thread and show the error message        Dispatcher.BeginInvoke(() => MessageBox.Show("Error getting user info:nn" + e.Message));    }}

Conclusion

So with these couple Facebook SDK api calls, we have created a new Facebook Connect session and retrieve the current users information. Personally I think that this takes one more step than necessary, but the calls are pretty straightforward. The next post will go over getting the list of friends for our current user and then getting the Profile Picture photo album for each friend.

Code!

Here is a download of a small demo application that uses the steps that were just discussed. In order to run the application, you will need to set up your own Facebook application. Until next time, Sláinte!

Download

Silverlight 4: Webcams to the 3rd Dimension

The 3rd Dimension

Recently at work, my coworker Jimm Wagner thought it would be fun to see if we could accomplish creating a “live” 3d video using Silverlight 4, a couple of webcams, and some old school red and blue 3d glasses. With the new webcam support that is now available in Silverlight 4, making this work was actually very simple. The resulting 3d in the video isn’t perfect, but there is some feeling of depth once the videos are aligned properly.

Getting Started

The basics for how to accomplish this are quite simple, use the new webcam support in Silverlight 4 to get a list of available video devices, take a couple of Rectangles and fill them with a video brush, and create a couple of pixel shaders to get the colors you want. A little more detailed look at how this all goes together, plus a download of the code, will be available below.

Click here to run the demo. Note: You will need the the Silverlight 4 runtime and at least 1 webcam plugged into your computer for the demo to work. The runtime is available for both Windows and Mac.

The Pixel Shaders

To create these pretty simple pixel shaders, I utilized the Shazzam Pixel Shader Utility to create the HLSL for the desired effects. The two effects that were created were Red Only, which removed any color from the image besides the red, and a Minus Red, which removed both the red and the alpha from the input source. The code for the fx files is as follows:

RedOnly.fx

sampler2D input : register(s0);// This shader will remove the green and blue colors from the sourcefloat4 main(float2 uv : TEXCOORD) : COLOR  {    float4 color= tex2D( input , uv.xy);    // remove green and blue    color.g = 0;    color.b = 0;    return color;}

MinusRed.fx

sampler2D input : register(s0);// This shader will remove the red color and alpha from the sourcefloat4 main(float2 uv : TEXCOORD) : COLOR  {    float4 color= tex2D( input , uv.xy);    // remove red and alpha    color.a = 0;    color.r = 0;    return color;}

One handy feature in the Shazzam tool is that it will generate the postscript files as well as the .Net classes that you need to implement your pixel shaders. More info can be found on the Shazzam site.

The Silverlight

So the first thing we need to do is the get all of the available webcams that are plugged into the computer. This is handled in the main page loaded event of our main window. Once we get a list of available video cameras, we check to see how many were found. If there is only a single camera, we go head and set one of our sources to that camera. Otherwise, we will bind a couple of comboboxes to the list of our available cameras so that the sources can be set at a later time.

void MainPage_Loaded(object sender, RoutedEventArgs e){    // get available devices    ReadOnlyCollection devices = CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices();    _deviceCount = devices.Count;    if (_deviceCount == 1)    {        // enable the capture and reset buttons        this.btnCapture.IsEnabled = true;        this.btnReset.IsEnabled = true;        // disable the source selections        this.btnSetSource.IsEnabled = false;        this.cbRedWebCamOptions.IsEnabled = false;        this.cbBlueWebCamOptions.IsEnabled = false;        // check if red source is null        if (_redSource == null)            _redSource = new CaptureSource();        // set the red source capture device        _redSource.VideoCaptureDevice = devices[0];        // check if blue source is null        if (_blueSource == null)            _blueSource = new CaptureSource();    }    else    {        // bind the combo boxes        this.cbRedWebCamOptions.DataContext = devices;        this.cbBlueWebCamOptions.DataContext = devices;    }}

So if we have more than one available video device, we will set the VideoCaptureDevice of each source in the click event of our btnSetSources button that will be enabled if more than one camera is found. We will also check to see if the same camera is chosen for both sources and will only use our _redSource if this is true.

// check if red source is nullif (_redSource == null)    _redSource = new CaptureSource();// check if blue source is nullif (_blueSource == null)    _blueSource = new CaptureSource();if (this.cbRedWebCamOptions.SelectedItem as VideoCaptureDevice == this.cbBlueWebCamOptions.SelectedItem as VideoCaptureDevice){    _sourcesAreSame = true;    // set video capture device    _redSource.VideoCaptureDevice = this.cbRedWebCamOptions.SelectedItem as VideoCaptureDevice;}else{    _sourcesAreSame = false;    // set video capture device    _redSource.VideoCaptureDevice = this.cbRedWebCamOptions.SelectedItem as VideoCaptureDevice;    _blueSource.VideoCaptureDevice = this.cbBlueWebCamOptions.SelectedItem as VideoCaptureDevice;}

And now that we have our capture devices initialized, we can create our video brushes and start the capture. If there is only a single camera, we will set it up so that our two video brushes are using the same camera. If the camera(s) are already running, we will stop the capture and reset our rectangles.

void btnCapture_Click(object sender, RoutedEventArgs e){    try    {        if (_redSource.State != CaptureState.Started && _blueSource.State != CaptureState.Started)        {            // make sure sources are stopped            _redSource.Stop();            _blueSource.Stop();            // create red video brush if null            if (_redBrush == null)            {                _redBrush = new VideoBrush();                _redBrush.Stretch = Stretch.Uniform;            }            // create blue video brush if null            if (_blueBrush == null)            {                _blueBrush = new VideoBrush();                _blueBrush.Stretch = Stretch.Uniform;            }            // check the number of devices            if (_deviceCount == 1 || _sourcesAreSame)            {                // set the red video brush source and rectangle fill                _redBrush.SetSource(_redSource);                this.RedRectangle.Fill = _redBrush;                // set the blue video brush source and rectangle fill                // since there is only one camera, both of the video brushes source will be the same                blueBrush.SetSource(_redSource);                this.BlueRectangle.Fill = _blueBrush;                // we offset the red rectangle to try and create the 3d effect for only one camera                this.sldRedHorizontal.Value = -5;                // ask user for permission                if (CaptureDeviceConfiguration.AllowedDeviceAccess || CaptureDeviceConfiguration.RequestDeviceAccess())                {                    _redSource.Start();                }            }            else            {                // set the red video brush source and rectangle fill                _redBrush.SetSource(_redSource);                this.RedRectangle.Fill = _redBrush;                // set the blue video brush source and rectangle fill                _blueBrush.SetSource(_blueSource);                this.BlueRectangle.Fill = _blueBrush;                // ask user for permission                if (CaptureDeviceConfiguration.AllowedDeviceAccess || CaptureDeviceConfiguration.RequestDeviceAccess())                {                    _redSource.Start();                    _blueSource.Start();                }            }            // change capture button content            this.btnCapture.Content = "Stop";        }        else        {            // stop input sources            _redSource.Stop();            _blueSource.Stop();            // remove the rectangles fill            this.RedRectangle.Fill = null;            this.BlueRectangle.Fill = null;            // reset capture button content            this.btnCapture.Content = "Capture";            // reset the rectangles            ResetRectangles();        }    }    catch (Exception ex)    {        MessageBox.Show(ex.Message, "Error using webcam", MessageBoxButton.OK);    }}

The final piece to the puzzle is using the pixel shaders that we created and compiled above. We add them in the xaml by adding in the following namespace xmlns:shaders=“clr-namespace:WebCam3d.Shaders” and then referencing it as follows:

<!-- On our Red Rectangle --><Rectangle.Effect>    <shaders:RedOnlyEffect /></Rectangle.Effect><!-- On our Blue Rectangle --><Rectangle.Effect>    <shaders:MinusRedEffect /></Rectangle.Effect>

Finally, I added in a couple of horizontal and vertical sliders that allow you to shift the two rectangles to get them lined up correctly for the 3d effect. This helps when using two different model webcams or just a single camera for input, plus the fact that my rig took slightly less time to develop than this one.

Conclusion

Hopefully this post was able to show how easy it is to implement multiple webcams in Silverlight 4 and add some simple effects to them as well. I am relatively new to Silverlight, but was still able to get a working demo up and running in a short amount of time using these techniques. Any comments or questions and suggestions on how this could be made better are more than welcome. Happy coding!

Code Download

Visual Studio 2010 RC Solution: WebCam3d.zip (78.00 kb)