preview

How to Create an Image Gallery Powered by Picasa

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.

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!


Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.fatlizardmedia.com Juan C Rois

    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.

    • http://blog.315design.com/ Mikhail Kozlov

      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.

  • http://www.philohermans.com Philo

    Nice Tutorial! :)
    And outcome looks good.

  • Michael

    Is there a demo link somewhere?

    • m

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

    • w1sh

      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.

      • http://www.pixelsoul.com pixelsoul

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

        I agree you should not come back here :P

      • David

        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!

  • http://os.laroouse.com/ esranull

    thanks, I need it

  • http://www.wesbos.com Wes Bos

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

  • Bretticus

    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!

  • deyon

    @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.

    • http://www.fatlizardmedia.com Juan C Rois

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

  • mark

    demo???

  • Misha

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

    MOLODEZ:)

    • http://www.mikhailkozlov.com/ Mikhail Kozlov

      Спасибо.

      • http://ramon.com.ua Ramon

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

  • http://www.innovacube.com/ HasanG

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

  • http://blog.315design.com/ Mike

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

    • http://lumpenstudio.com kbs

      Mike- This tut looks very promising. But I suggest you move this Demo link up into Introduction. I too was wanted to see it first to be sure it was for me. This is where I finally found it. But like others I was annoyed. Now I will see if I can make it happen. Thanks

  • Elaine Chua

    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.

  • dc

    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

  • William Rouse

    Is the location for the “loading gif” correct?

    It does not seem to be working for me.

  • http://www.xtensives.com Hasanga

    cool stuff! Picasa got a brilliant API.

  • gordonek

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

  • John

    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.

  • Black

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

    • http://www.mikhailkozlov.com/ Mikhail Kozlov

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

  • Andreas

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

  • http://www.nourl.com Vinnie

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

  • http://www.nourl.com Vinnie

    Is it SEO Friendly?

  • Abhijeet

    nothing new …………..

    wordpress gallery plugins modified…………..

    i m right????

  • http://redstage.com/magento Redstage Magento

    The outcome was very promising. Good job!

  • http://www.maqicmeow.de Maqic Meow

    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/” ?

    • http://www.mikhailkozlov.com/ Mikhail Kozlov

      maqicmeow is most likely your ID

  • http://www.radiomorava.rs Milan

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

  • baiznov

    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.

  • http://vfxboy.co.cc ganesh

    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.

  • Victor

    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 =/

  • Luis

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

  • Paul Robinson

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

  • fantasy

    Fantastic all in one tuts. Thanks for it

  • MrJeff

    the css file 960.CSS and the reset.CSS are not included, can someone upload or give a link please…

    thank you^^

  • Rohit Pal

    The link http://schemas.google.com/photos/2007 is not working and so does the code not working. Can anyone help me? ? Thanks in advance

  • Webrunner

    Your code is great GREAT! Just one thing for those who dowload your package, those links are broken

    So download 960.css and put it on your server instead.

    I have one request, I don’t find a way to modify the size of the viewport: how to shrink the albums window ?

    if I change

    $(“div.scrollable”).scrollable({size: 10, // number of pictures per page
    to size: 5

    I have 5 pics, but I don’t find how to shrink the container…

    Thanks for the help

  • Webrunner

    I played with the code a little and added a tooltip (tipTip jQuery Plugin) over albums and pictures.
    Final zip here : http://webrunner.org/sandbox/sandbox.zip

  • frustrated

    this page will help you adjust the width of the overall layout to fit your page design.

    http://www.spry-soft.com/grids/

  • Villas

    Im trying hard here but the script dont show my photos? !

  • http://tandon1@blogger.com Nikisa

    Why need server side when you can just do it with only client side scripting using JSON, Yahoo Pipes and feeds etc.

    Niki

  • http://www.eatonrealtyllc.com sceaton

    Hello!

    Just wanted to compliment your fantastic work! Also, one edit: _conf != _code The heading above reads “_code” instead of “_conf”

    Again, great job!

  • Robson

    Accentuation does not work? My native language is accent in words. how can I fix?

  • largan

    I feel a bit stupid… but how can I set the gallery width to fit into 650px.

  • Glaudston

    I can’t get the images to show here on my end.. http://www.glaudston.com/photo/

    I even tried downloading the source to see if I missed something and still get nothing!

  • Paul J

    Anyway to make it access only private picasa albums? I tried access=private (instead of public) but it did not work.

  • http://www.gebzemedya.com gebze medya

    Thank you excellent…

  • David Karigithu

    Downloaded the source code and when I ran it on my web server it doesn’t display the images but when I use firebug and toggle some of the CSS the images all display, notably overflow and the position properties.

    HELP??!

    • rukawa

      re-download two files-reset.css、960.css

      and chane follow code

      It work

  • Safuan

    Thanks, worked like a charmed… just some of the css I’ve copied from the original site to my test site.

  • Ngan

    There seem to have a bug now, the photos within an album don’t show thumbnail anymore, instead, just directly show the full size image.

  • Ngan

    Bug fixed !! The photo feed from the album returns one more entry in the THUMBNAIL, which first one is the full size while the second one is the 72c (72 pixels cropped, if you haven’t change)… I don’t know why Picasa did that, I only realise it today when my album didn’t work like it was yesterday.

    so just simply replace this line of code in the _ajax.php:

    $a = $group[0]->attributes();
    to
    $a = $group[1]->attributes();

  • mzi

    just what I was looking for :) very awesome tutorial, this made my day!

  • http://almpt.com Vishnu

    I like your Photo Gallery too much and I want to use your code for the non profit organisation that I am working for.

    I am new to PHP and I followed steps and updated index.php as described but get errors on browser.

    registerXPathNamespace(‘gphoto’, ‘http://schemas.google.com/photos/2007′);

    Could you please upload source file so that we have to change minimum variables(like username). May be the code of demo will be good.

    Pl. help this can change life of many people by exposing there work.