preview

How to Create an Image Gallery Powered by Picasa

Oct 20th, 2009 in JavaScript & AJAX by Mikhail Kozlov

In this tutorial we are going to create a simple image gallery powered by Google's Picasa Web Albums. In order to enhance the user's experience, we'll throw some jQuery into the mix and create a scrollable album carousel.

PG

Author: Mikhail Kozlov

This is a NETTUTS contributor who has published 1 tutorial(s) so far here. Their bio is coming soon!

Final Product

Overview

We are going to use PHP's SimpleXML extension to sort and access the data inside the XML feed provided by Picasa Web Albums. jQuery will be responsible for the DOM manipulation and AJAX request. We are also going to use the Scrollable library, which is part of jQuery Tools to create the carousel. Next, we'll use jQuery's MouseWheel plug-in to allow for cross-browser mouse wheel support. Finally, we'll use the Fancybox plug-in to each image in a "lightbox."

What We Need

Getting Started

We'll begin by downloading the files and putting them into the same folder. I also combined all of the Fancybox images with jQuery Tools ones, and placed them inside the img folder.

PHP files

For our project, we are going to use following PHP files:

  • index.php
  • _ajax.php
  • _conf.php
  • index.php will be responsible for displaying albums, images, and sending requests to _ajax.php.
  • _ajax.php will be handling dynamic request and returning formatted thumbnails
  • _conf.php, as you may have guessed, will contain some configuration information that will be used by both files.

_code.php

This file is very simple and short.

// First we need to set some defaults
$gTitle=""; // title of your gallary, if empty it will show: "your nickname' Photo Gallary"
$uName= "kozlov.m.a"; // your picasaweb user name
$tSize="72c"; // thumbnail size can be 32, 48, 64, 72, 144, 160. cropt (c) and uncropt (u)
$maxSize="720u"; // max image size can be 200, 288, 320, 400, 512, 576, 640, 720, 800. These images are available as only uncropped(u) sizes.

Basically, in this file we set the username (Picasa Web Album ID), thumbnail size, and max image size that we are going to show in our gallery.

index.php

This file requires a bit more to make the gallery work. We begin with referencing our configuration file (_conf.php):

<?php
include './_conf.php'; // getting constants

Next we need to load the album feed. We are only retrieving publicly available albums, so our request will look something like: "http://picasaweb.google.com/data/feed/api/user/user_name?kind=album&access=public".


$file = file_get_contents("http://picasaweb.google.com/data/feed/api/user/".$uName."?kind=album&access=public&thumbsize=".$tSize);

file_get_contents will load content from the XML feed into $file variable. As you can see, we used the $uName variable defined in _conf.php to get the right feed. We also passed the additional parameter "thumbsize;" so that the returned feed will contain thumbnails of our chosen size.

Now, let's convert the contents of the feed into a SimpleXml object and define the namespaces we are going to use:

$xml = new SimpleXMLElement($file);
$xml->registerXPathNamespace('gphoto', 'http://schemas.google.com/photos/2007');
$xml->registerXPathNamespace('media', 'http://search.yahoo.com/mrss/');

You can find all namespaces used in the API feeds by visiting http://code.google.com/apis/..., but we'll only be using "media" and "gphoto" in our tutorial; you do not have to worry about the rest of them.

Next, we'll get the web album's name in case we did not already set one in __conf.php file:

if($gTitle == null){ // if empty Gallery title will be "user id's  Photo Gallery"
$nickname = $xml->xpath('//gphoto:nickname'); // Mikhail
$gTitle =$nickname[0]."'s Photo Gallery";
}
?>

Finally, it is time for some simple HTML. We'll set our header and reference a few CSS files.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title><?php echo $gTitle; ?></title>
<link rel="stylesheet" href="reset.css" type="text/css" />
<link rel="stylesheet" href="960.css" type="text/css" />
<link rel="stylesheet" href="style.css" type="text/css" />
<link rel="stylesheet" href="fancybox.css" type="text/css" />
</head>
<body>
<div class="container_16">
<div class="grid_16">
<?php echo "<h1>". $gTitle ."</h1>";?>

As you can see, we've set the page title to $gTitle and have added some CSS to make things pretty.

Style Files

I do not think that reset.css needs any additional explanation, so let's skip over it and take a closer look at the other stylesheet.

  • 960.css allows for a more grid-like layout.
  • style.css comes from the provided stylesheet from jQuery Tools.
  • And fancybox.css is part of the FancyBox plug-in.

Note: Please make sure that you change image path in both fancybox.css and style.css, so all background images point to img folder.

Album Holder and Navigational Elements

It is time to create our album holder and navigational elements. This is where jQuery Tools is a huge help. For the album navigation, we'll be using the Scrollable library. If you visit the Scrollable reference page and take a look at some of the examples, you'll see that we're using it almost without any modifications.

<div>
<a id="prev">&nbsp;</a> <!-- Prev controll-->
</div>
<div id="albums">
<div>
<!-- php code will go here -->
</div>
</div>
<div>
<a id="next">&nbsp;</a><!-- Next controll-->
</div>
<div>&nbsp;</div>
<div id="navi"></div> <!-- Pagination holder-->
<div>&nbsp;</div>

We'll also need a holder for the album picture thumbnails, and the album title that will be loaded via AJAX:

<h2 id="a_title"></h3>
<div id="pic_holder">
</div>
</div>
</div>

JavaScript

Let's finish our page by referencing the JavaScripts we'll be using.

<script type="text/javascript" language="JavaScript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js"></script>
<script type="text/javascript" language="JavaScript" src="jquery.tools.min.js"></script>
<script type="text/javascript" language="JavaScript" src="jquery.easing.1.3.js"></script>
<script type="text/javascript" language="JavaScript" src="jquery.fancybox-1.2.1.pack.js"></script>
</body>
</html>

PHP

Now it is time to go through the XML file and sift the album thumbnails out. Place the following PHP code inside the </div class="items"> element.

<?php
foreach($xml->entry as $feed){
$group = $feed->xpath('./media:group/media:thumbnail');
$a = $group[0]->attributes(); // we need thumbnail path
$id = $feed->xpath('./gphoto:id'); // and album id for our thumbnail
echo '<img src="'.$a[0].'" alt="'.$feed->title.'" title="'.$feed->title.'" ref="'.$id[0].'" />';
?>
}

Our plan was to load album pictures once visitors click on a specific thumbnail, therefore we have to create some kind of reference to connect the two. For this purpose, we are putting a ref attribute into each album's img tag; so it will look something like this when compiled:

	<img ref="5364767538132778657" title="2009-07-31 - Beach Ocean City, MD" alt="2009-07-31 - Beach Ocean City, MD" src="http://lh4.ggpht.com/_X7imT2xUAEM/SnN7pvTzfqE/AAAAAAAAHmg/DNWeIS7JGzg/s72-c/20090731BeachOceanCityMD.jpg" />

AJAX

Finally, we'll spice it all up with some jQuery. Firstly, we need to initialize the jQuery Tools plug-in with some additional parameters:

$("div.scrollable").scrollable({
	size: 10, // number of pictures per "page"
	next: '#next', // id of next control element
	prev: '#prev', // id of prev control element
	navi:'#navi' // id of navigation control holder
});

The code above will automatically add scrollable controls.

Note: It is better to set the scrollable size to an odd number. This way, selected images will appear right in the middle.

Next we'll create on click event for the album thumbnail:

$("#albums img").bind("click", function(){
	$("#a_title").text($(this).attr('title'));
	$("#pic_holder").html('<div><img src="/images/loading.gif" alt="Loading..."></div>').load("_ajax.php",{"aID":$(this).attr("ref")},function(){
	$("#pic_holder").find("a").fancybox();
	});
});

Let's take close look at what we are doing here. First we define our click event trigger:

$("#albums img").bind("click", function(){

We use bind instead of the simple click because we do not want to interrupt the work of the scrollable plug-in that we just initiated above.

Next, we'll apply the album title into the h2 tag with id "a_title" from the title attribute of the anchor tag:

	$("#a_title").text($(this).attr('title'));

Finally, we send an AJAX request to _ajax.php and let Fancybox re-index the freshly loaded images:

$("#pic_holder").html('<div><img src="/images/loading.gif" alt="Loading..."></div>').load("_ajax.php",{"aID":$(this).attr("ref")},function(){
 	$("#pic_holder").find("a").fancybox();
});

As you probably noticed, we are inserting a "loading image" inside "pic_holder" before sending the AJAX request. This will provide the user with some feedback to let them know that their request is currently being processed. Once we receive a response from the server, jQuery will replace the contents of the "pic_holder" with data that came from _ajax.php.

_ajax.php

Now it is time to serve the contents of the album to our visitors. Our plan is to show thumbnails linked to originals on the Picasa server. Once a thumbnail is clicked, Fancybox will take over and create a lightbox-like image gallery. We'll start with the entire contents of the file, and then go over each line:

<?php
	include './_conf.php'; // getting constants
	if(isset($_POST['aID'])){
		$aID = $_POST['aID']; // let's put album id here so it is easie to use later
		$file = file_get_contents('http://picasaweb.google.com/data/feed/api/user/'.$uName.'/albumid/'.$aID.'?kind=photo&access=public&thumbsize=72c&imgmax='.$maxSize); // get the contents of the album
		$xml = new SimpleXMLElement($file); // convert feed into SimpleXML object
		$xml->registerXPathNamespace('media', 'http://search.yahoo.com/mrss/'); // define namespace media
		foreach($xml->entry as $feed){ // go over the pictures
		$group = $feed->xpath('./media:group/media:thumbnail'); // let's find thumbnail tag
		$description = $feed->xpath('./media:group/media:description'); // file name appended by image captioning
		if(str_word_count($description[0]) > 0){ // if picture has description, we'll use it as title
			$description = $feed->title. ": ". $description[0];
		}else{
			$description =$feed->title; // if not will use file name as title
		}
		$a = $group[0]->attributes(); // now we need to get attributes of thumbnail tag, so we can extract the thumb link
		$b = $feed->content->attributes(); // now we convert "content" attributes into array
		echo '<a rel="'.$aID.'" href="'.$b['src'].'" title="'.$description.'"><img src="'.$a['url'].'" alt="'.$feed->title.'" width="'.$a['width'].'" height="'.$a['height'].'"/></a>';
		}
	}else{
		echo 'Error! Please provide album id.';
	}
?>

First, we are going to reference our configuration file, so we can have access to the constant parameters: Picasa ID and thumbnail size.

include './_conf.php'; // getting constants

Then we'll check if the album ID was sent via POST request:

if(isset($_POST['aID'])){

If we did not find an album ID, we're simply going to print an error message:

}else{
   echo 'Error! Please provide album ID.';
}

If _ajax.php received the album ID, we'll get an XML feed and start working on it, so let's create a link to the correct XML feed:

 $aID = $_POST['aID']; // let's put the album id here so it is easier to use later
 $file = file_get_contents('http://picasaweb.google.com/data/feed/api/user/'.$uName.'/albumid/'.$aID.'?kind=photo&access=public&thumbsize=72c&imgmax='.$maxSize); // get the contents of the album

As you can see, we use the album ID that came via the POST request as well as constants from _conf.php file. Again, we are using file_get_contents to load the XML feed and store it in the $file variable. Next we convert it to a SimpleXMLElement object cycle through each entry nodes that contain information about each picture. To do so, we'll use a simple foreach() loop.

foreach($xml->entry as $feed){ // go over the pictures

Next, we are ready to extract data needed for our link and thumbnail. I've commented every line and hopefully it is enough to understand what is going on:

$group = $feed->xpath('./media:group/media:thumbnail'); // let's find the thumbnail tag
$description = $feed->xpath('./media:group/media:description');  // let's find the description tag
if(str_word_count($description[0]) > 0){ // if the picture has description, we'll use it as the title
	$description = $feed->title. ": ". $description[0]; // file name appended by image captioning
}else{
	$description =$feed->title; // if not, will use file name as title
}
$a = $group[0]->attributes(); // now we need to get attributes of thumbnail tag, so we can extract the thumb link
$b = $feed->content->attributes(); // now we convert "content" attributes into array

Finally, we are putting it all into HTML context. We'll echo a link to the original image and thumbnail image:

echo '<a rel="'.$aID.'" href="'.$b['src'].'" title="'.$description.'"><img src="'.$a['url'].'" alt="'.$feed->title.'" width="'.$a['width'].'" height="'.$a['height'].'"/></a>';

To force Fancybox to organize all of the images into a gallery, we are adding the rel attribute to each link. You can simply put same number or string as value, but I'm going to use the album ID.

Styling

As I mentioned before, most of the styling was taken straight from examples at the jQuery Tools website. All you must do here is simply adjust the height and width to suit the design of your website.

Mouse Wheel Scroll

Mouse Wheel Scroll is another beauty that you can easily use. As some may have noticed, we never initiated this plug-in; yet, if you hover over the album carousel and try to scroll with your mouse wheel, it will work thanks to jQuery Tools.

Conclusion

We've learned how to combine PHP's SimpleXML extension with a handful of plugins and Picasa to create a beautiful and dynamic image gallery. I hope you enjoyed and learned from it!


Related Posts

Check out some more great tutorials and articles that you might like

Enjoy this Post?

Your vote will help us grow this site and provide even more awesomeness

Plus Members

Source Files, Bonus Tutorials and
More for $9 a month for all TUTS+
sites in one subscription.

Join Now

User Comments

( ADD YOURS )
  1. PG

    Juan C Rois October 20th

    It is a very nice implementation of different technologies, my compliments to the author, but unless I’m missing something, what’s the need of Picasa?. I mean, if we are going to use as much PHP, AJAX and jQuery, can’t we create the galleries and albums without Picasa altogether?

    Just curious? Thanks for the tutorial though.

    ( Reply )
    1. PG

      Mikhail Kozlov October 20th

      I use Picasa to organize my pics and share photos with friends and family. Originally I made tool to convert picasa links to BBcode and them people starting to send me e-mails asking how they can use it on there website to show pictures, so this is how.

      ( Reply )
  2. PG

    Philo October 20th

    Nice Tutorial! :)
    And outcome looks good.

    ( Reply )
  3. PG

    Michael October 20th

    Is there a demo link somewhere?

    ( Reply )
    1. PG

      m October 20th

      i was looking for the same thing, am i missing it??

      ( Reply )
    2. PG

      w1sh October 20th

      Yeah. I can understand why some things don’t have demos, but c’mon…
      I mean…

      C’mon.

      If that doesn’t convince you to pull this tutorial until a demo is HEAVILY available, then I’m not coming back here.

      ( Reply )
      1. PG

        pixelsoul October 20th

        A little over reacting about his comment aren’t you? I mean c’mon…

        I agree you should not come back here :P

      2. PG

        David October 23rd

        I won’t come back here until the website’s background turned red! This is outrageous to have such a white background! :D

        w1sh, if that doesn’t convince you to become smart… Well, don’t come back!

  4. PG

    esranull October 20th

    thanks, I need it

    ( Reply )
  5. PG

    Wes Bos October 20th

    yeah a demo link would be great, kind of hard to juge if this is worth doing by looking at the code

    ( Reply )
  6. PG

    Bretticus October 20th

    Wow, very impressive tut. It’s amazing what some javascript smiths can hammer out! Kudos to jquery for creating a great plugin architecture to mash them together and kudos to Mikhail for showing us how to put this all together. Definitely very smooth. Picasa is a very convenient way to upload and manage pictures. This makes showing them on your own sites an even more attractive notion.

    Thanks again!

    ( Reply )
  7. PG

    deyon October 20th

    @Juan
    The main reason I can see for using picasa is that the software “picasa” is so easy to organize and rearrange a huge amount of photos and upload. Its alot better then just dragging a heap of photos to an ftp. Especially for clients who can’t ftp.
    I personal know a handful of people who use picasa to share photos. Not only that but my picasa album links to my facebook which saves me the trouble of uploading twice. I guess now I can link images to facebook, my website and still have the original picasa album.

    ( Reply )
    1. PG

      Juan C Rois October 20th

      Fair enough, thanks for the explanation. I just have not had the chance to use Picasa.

      ( Reply )
  8. PG

    mark October 20th

    demo???

    ( Reply )
  9. PG

    Misha October 20th

    Excellent tutorial.
    I was about to use the generic picassa embed but this is much better.

    MOLODEZ:)

    ( Reply )
    1. PG

      Mikhail Kozlov October 21st

      Спасибо.

      ( Reply )
      1. PG

        Ramon October 21st

        Русские идут :) Странно, что именно русский написал об объединении Пикасы и jQuery, хотя странность исчезает, поскольку туториал появился на tutsplus. Может, нужен даблпост на Хабре? :)

  10. PG

    HasanG October 20th

    Hey, thanks! I’ve just figured out that we can use a xml file of our Picasa gallery :)

    ( Reply )
  11. PG

    Mike October 20th

    Thanks for feedback everybody. You can check out live demo here http://cmp.315design.com/tools/picasatoweb/demo/

    ( Reply )
  12. PG

    Elaine Chua October 20th

    This is seriously good job and finally the solution to one of my project headache!

    I have a client who needs an image gallery, who can’t upload via and don’t know how to resize images to create thumbs and originals and want an easy uploading interface for organising.

    ( Reply )
  13. PG

    dc October 20th

    Hey, this is pretty awesome! I’ve been looking for something like this for ages.

    I’m guessing this wont work for videos, though? I commonly upload a dir full of pics and vids. what do you think, can this be modded to show vids as well?

    thanks!
    dc

    ( Reply )
  14. PG

    William Rouse October 20th

    Is the location for the “loading gif” correct?

    It does not seem to be working for me.

    ( Reply )
    1. PG

      Mikhail Kozlov October 20th

      sorry about that here is the file http://cmp.315design.com/images/loading.gif.

      ( Reply )
  15. PG

    Hasanga October 20th

    cool stuff! Picasa got a brilliant API.

    ( Reply )
  16. PG

    gordonek October 21st

    i dont understand why to write so many stuff if its not needed.
    U can implement picassa album on website much easier.

    ( Reply )
  17. PG

    John October 21st

    Is there a way to just have the individual photos show up and not the album? So right when you enter a page, you see all of the photos instead of having to click on an album cover first.

    ( Reply )
  18. PG

    Black October 21st

    Great tutorial! Question: How can I view my “Unlisted” albums ?

    ( Reply )
    1. PG

      Mikhail Kozlov October 21st

      It will require authorization to PicasaWeb and was not part of this tutorial. Probably good subject for another tutorial.

      ( Reply )
  19. PG

    Andreas October 22nd

    wow i think this is a great possibility to outsource my image galleries… i think im gonna write an joomla compontent for this feature…

    ( Reply )
  20. PG

    Vinnie October 22nd

    DEMO PLEASE? is it worth doing ? anyone who has tried it can post a demo link…

    ( Reply )
  21. PG

    Vinnie October 22nd

    Is it SEO Friendly?

    ( Reply )
  22. PG

    Abhijeet October 23rd

    nothing new …………..

    wordpress gallery plugins modified…………..

    i m right????

    ( Reply )
  23. PG

    Redstage Magento October 23rd

    The outcome was very promising. Good job!

    ( Reply )
  24. PG

    Maqic Meow October 24th

    Hey!

    This is very cool, but i don’t know what my Picasa Web Album ID is.

    Do you mean this: “http://picasaweb.google.com/maqicmeow/” ?

    ( Reply )
    1. PG

      Mikhail Kozlov October 28th

      maqicmeow is most likely your ID

      ( Reply )
  25. PG

    Milan October 31st

    Thanks man! This is what I needed for my 6.000 images.

    ( Reply )
  26. PG

    baiznov November 2nd

    1 hic-up, allow_url_fopen should be ON in PHP configuration,
    so not all can use this solution, but great tuts btw,
    if there is a way to download the xml n read locally that would be best.

    ( Reply )
  27. PG

    ganesh November 14th

    thanks for the tut, one question. can i reference paritcular albums for a page.

    for example,In this tut you refer all public albums, and I have A,B,C and D has public albums. lets say i want to display album A, B in one page and C,D in another, how can I do that.

    ( Reply )
  28. PG

    Victor November 23rd

    It´s possible to put another number to the number of the thumbs? For example, now is 10 for line, and if I need put 5? I didn´t get this =/

    ( Reply )
  29. PG

    Luis November 25th

    I tried to do the same thing, but i just wanna show an album no the entire gallery??? some ideas.. some help????

    ( Reply )
  30. PG

    Paul Robinson January 14th

    its it possible to display album names with the thumbnails?
    using php image processor to print album names on the thumbnail?

    ( Reply )
  31. PG

    fantasy January 31st

    Fantastic all in one tuts. Thanks for it

    ( Reply )
  1. Arrow
    Gravatar

    Your Name
    January 31st