Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Modern Scrapbook

3.33/5 (2 votes)
24 Jul 2013CPOL4 min read 15K  
Touch enabled application for creating scrapbooks from social service hosted pictures.

This article is an entry in our AppInnovation Contest. Articles in this sub-section are not required to be full articles so care should be taken when voting.

Introduction

The past few years have seen a proliferation of smartphones, social media usage, and cloud hosted storage. All of this has added up to a massive amount of personal photos stored and shared in various ways. People used to assemble their photos into physical scrapbooks, but that has not translated well into the digital realm. Users don't want to have to right-click and download images to their local computer in order to awkwardly crop/resize and assemble the photos in programs that weren't specifically designed for it (Word, PowerPoint, Paint...). My app idea is an attempt at bringing the old art of scrapbooking back into this new age of digital photos. 

The Application 

Image 1 

Image 2 

 Ultra Scrapbook is an application which lets users view and pull in photos from the popular services they rely on. The user can then assemble the photos onto a Canvas where they can position and resize. Scrapbooks can have multiple pages and each page will contain photos and text captions.

My app is especially geared toward the new class of All in Ones (AIO)'s with large vibrant touch screens. The Intel Core processors are the perfect solution for powering this graphically intensive application to give the user a smooth and jitter free experience.  The app will appeal across generations as the large screens of todays AIO's are perfect for the whole family to have fun building scrapbooks together.  The multi-touch interface will let even the youngest and oldest members interact with the application intuitively. 

Features

  • Login with Facebook Credentials 
  • View and pull in photos associated with you on FB
  • Add, arrange, and re-size photos on a canvas
  • Output canvas to JPEG or PDF
  • Your project persists in the cloud (Azure) and is tied to your FB credentials

Future Features

  • Integrate with Microsoft, Google, Twitter, and other services to allow mixing photos from multiple services. 
  • Associate Check-in information with Scrapbook for user to create timeline type story 
 

Using the code 

The app will be written in C# using WPF. Users profile and project data will be stored on a web service hosted through Azure. The app will ingest data through REST calls. The web service itself will be an ASP.NET MVC 4 project that communicated with Facebook using calls to the Graph API.  For the purposes of this contest, I will focus on using Facebook, the most popular social network. But the app will be designed in a generic way such that Google, Microsoft, Twitter, and other services can be integrated later.

 For Facebook we use the Facebook SDK for .NET.  Add it to the project by searching "Facebook" in NuGet Manager.  Here is a call we make to get the first 25 pictures associated with the user.  Note that "me" is used in place of a user ID to refer to the logged in user.

C#
//
var client = new Facebook.FacebookClient("yourAccessToken");
dynamic response = client.Get("me/photos", new { limit = 25, offset = 0});
//   

 The Get call returns us a dynamic object which is really a JSON object.  To parse it we check that it has a key named "data" and then iterate over its children.  I defined a Picture class to represent pictures.  We set a "SocialProvider" attribute to help us add other services in the future.   

C#
List<Picture> list = new List<Picture>();
          if (response.ContainsKey("data"))
          {
              foreach (var result in response["data"])
              {
                  Picture item = new Picture();
                  item.Id = null;
                  item.SourceId = result.id;
                  item.Name = result.name;
                  item.Link = result.link;
                  item.ImageUrl = result.picture;
                  item.BigImageUrl = result.source;
                  item.Date = DateTime.Parse(result.created_time);
                  item.Provider = SocialProvider.Facebook;
                  list.Add(item);
              }
          }

 Facebook stores several different resolutions of each image in a result.images array within the dynamic result.  In our app, a picture can only be associated with one source URL.  Therefore, when the user re-sizes the picture, we want to grab the optimal resolution.  But we don't want to just grab the highest possible resolution, so we look for the next highest based on the re-sized dimensions.   Using the ID of the picture, we can do a narrow query for just that picture. 

C#
dynamic response = client.Get(picture.SourceId);

            List<KeyValuePair<Size, string>> sizes = null;
            if (response.ContainsKey("images"))
            {
                sizes = new List<KeyValuePair<Size, string>>();
                foreach (var result in response["images"])
                {
                    sizes.Add(new KeyValuePair<Size, string>(new Size(Convert.ToInt32(result.width), Convert.ToInt32(result.height)), result.source));
                }
            }if (sizes != null)
            {
                //Figure out the best width and hieght.  Basically the best width is equal to actual width, or one level higher.  Same for height.
                Size bestWidth = new Size();
                Size bestHeight = new Size();
                string value = picture.ImageUrl;
                foreach (var item in sizes)
                {
                    if (bestWidth.Width == 0 ||
                        (bestWidth.Width < picture.Width && bestWidth.Width < item.Key.Width) ||
                        (bestWidth.Width > picture.Width && bestWidth.Width > item.Key.Width && item.Key.Width > picture.Width))
                    {
                        bestWidth = item.Key;
                    }
                    if (bestHeight.Height == 0 ||
                        (bestHeight.Height < picture.Height && bestHeight.Height < item.Key.Height) ||
                        (bestHeight.Height > picture.Height && bestHeight.Height > item.Key.Height && item.Key.Height > picture.Height))
                    {
                        bestHeight = item.Key;
                    }
                }

                //Set the optimal size to which ever size is the greatest.
                Size optimalSize = bestWidth.Width * bestWidth.Height > bestHeight.Width * bestHeight.Height ? bestWidth : bestHeight;

                return sizes.Find(p => p.Key.Equals(optimalSize)).Value;
            }   

 When I get further along, I plan to post more code dealing with communications between the client WPF application, and the Azure hosted web service.  I will be taking advantage of Azures free 20MB SQL database allocation to store information on users scrapbooks and pictures.  This will allow users to load their projects onto any W8 computer.  

I will also show how to use pinch to zoom and drag to re-size and position the pictures.  This will work great on the large touch screens of AIO computers. 

Points of Interest 

Facebook offers two methods of accessing its data. The Graph API and FQL. Unfortunately, neither is as powerful as I hoped. I thought I could do complex SQL like queries. But you get an error if you try to query on fields which aren't indexed. So I use the Graph API to get lists of general thing, such as the users photos or their checkins. FQL is used to query specific relationships, such as whether a photo is associated with a certain friend.

History 

7/24/2013: Original write up.

License

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