Embedding Picasa Web Albums with JavaScript

Over the weekend I moved the majority of the photographs from my photo albums stored with my hosting provider to Picasa Web Albums.  My original plan was to use Picasa's "paste HTML to embed in website" feature to link to the albums from my site, but a quick search of the internet turned up some simple JavaScript code demonstrating the ease with which Picasa Web Albums could be fully integrated with an external website.

The code, which was found on http://www.bloggingtips.com, implements a JavaScript-based Picasa Photostream Widget to display the last nine photographs posted to a Picasa web account.  With a few modifications to this code, including the addition of the Slimbox 2 jQuery plugin, I had some JavaScript code for embedding the contents of a Picasa Web Album within a nicely formatted page on my site, with Lightbox support:

<style type="text/css">
  #picasaPhotos img {border: 1px solid #000; margin: 5px 5px 5px 5px;}
</style>

<!-- Elements to receive the Picasa Web Album content -->
<h1 id="picasaTitle"></h1>
<pre id="picasaSubtitle"></pre>
<div id="picasaPhotos"></div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript"></script>
<script src="js/slimbox2.js" type="text/javascript"></script>
<link rel="stylesheet" href="css/slimbox2.css" type="text/css" media="screen" />

<script type="text/javascript">
  // Indexes to standard thumbnails returned by Picasa API
  var THUMB_SMALL  = 0;
  var THUMB_MEDIUM = 1;
  var THUMB_LARGE  = 2;

  // Sizes for photographs to be displayed by slimbox
  var PHOTO_SMALL  = 640;
  var PHOTO_MEDIUM = 800;
  var PHOTO_LARGE  = 1024;

  var DEFAULT_MARGIN    = 5;
  var DEFAULT_THUMBSIZE = THUMB_MEDIUM;
  var DEFAULT_PHOTOSIZE = PHOTO_MEDIUM;

  // Compute horizontal and vertical padding needed to make the image "square" so
  // landscape and portrait images align nicely on a grid
  function computePadding(width, height) {
    var hspace = 0;
    var vspace = 0;

    if (width > height) {
      vspace = (width - height) / 2;
    } else if (height > width) {
      hspace = (height - width) / 2;
    }

    return {"hspace": hspace, "vspace": vspace};
  }

  // Adjust margin style, using padding computed from image dimensions
  // hspace and vspace specify padding to make the area filled by the image seem "square"
  // margin is the padding to be placed on all sides of the image
  function imgMarginStyle(hspace, vspace, margin) {
    var hmargin = margin + hspace;
    var vmargin = margin + vspace;
    return "margin: " + vmargin + "px " + hmargin + "px " + vmargin + "px " + hmargin + "px;";
  }

  // Generate url for photo scaled to specified size
  function imgScaledUrl(url, size) {
    var split = url.lastIndexOf("/");
    return url.substring(0, split) + "/s" + size + url.substring(split);
  }

  function loadPicasaAlbum(userid, albumid, thumbsize, photosize, margin) {
    var ts = thumbsize || DEFAULT_THUMBSIZE;
    var ps = photosize || DEFAULT_PHOTOSIZE;
    var m = margin || DEFAULT_MARGIN;

    // Originally based on code from http://www.bloggingtips.com/2009/03/23/picasa-widgets-and-plugins-for-your-blog/
    $j = jQuery.noConflict();
    $j(document).ready(function(){
      $j.getJSON("https://picasaweb.google.com/data/feed/base/user/" + userid + "/album/" + albumid + "?kind=photo&access=public&alt=json-in-script&callback=?",
      function(data, status) {
        $j("#picasaTitle").text(data.feed.title.$t);
        $j("#picasaSubtitle").text(data.feed.subtitle.$t);

        $j.each(data.feed.entry, function(i, pic) {
          var thumb = pic.media$group.media$thumbnail[ts];
          var photo = pic.media$group.media$content[0];
          var desc = pic.media$group.media$description.$t;
          var pad = computePadding(thumb.width, thumb.height);

          $j("<img/>").attr("src", thumb.url)
                      .attr("alt", desc)
                      .attr("style", imgMarginStyle(pad.hspace, pad.vspace, m))
                      .appendTo("#picasaPhotos")
                      .wrap("<a href=\"" + imgScaledUrl(photo.url, ps) + "\" title=\"" + desc + "\" />");
        });
        
        $j("#picasaPhotos a").slimbox();
      });
    });
  }

  loadPicasaAlbum("myuserid", "myalbumid");
</script> 

You can see the code in action here.

If you would like to embed Picasa Web Albums within your own site, the code above should be everything needed to get you started.  You will need to specify your Picasa user ID and the desired album ID to the loadPicasaAlbum() function, and you will need to install a copy of the Slimbox 2 jQuery plugin on your site.  The Slimbox 2 jQuery plugin can be obtained here.  

I have also created a repository on Github containing all of the files necessary for embedding Picasa Web Albums, including jQuery and the Slimbox 2 jQuery plugin.  This repository will always contain the latest version of the code that I am using to embed Picasa Web Albums on my website.  You can find the repository here:

git://github.com/dgraves/embeddedalbums.git

 

Programming: 

Comments

Hello!

This is a fantastic script, and easy enough to get working for the (1) album you can specify at the end of the script, but how do I get the page to display more than one album, as you do on the demo page.  I've downloaded the source from Git to try that, but I still get nothing.  I'm guessing there are some variables that I'll have to set...?

 

Thanks!

Cory

Hi Cory,

I'm glad you find the script useful!  To display multiple albums on a page you can use the generateAlbumThumbs function found in the albumthumbs.js file that is in the GitHub repository.  First you'll need to create an array of Javascript objects that contain properties describing the album to be displayed.  The required album properties are:

  • URL for the page to load when the album thumbnail or title is clicked
  • URL for the image to be used for the album thumbnail
  • Album title
  • Album date
  • Number of photographs or albums contained by the album

Once the array has been created you just pass it and the ID of the HTML element that you want to contain the album list to the generateAlbumThumbs function.  

Here is an example:

<div id="albums"></div>
<script src="albumthumbs.js" type="text/javascript"></script>
<script type="text/javascript">
var albums = [
  {"url": "/photographs/yumaprison",
   "img": "https://lh4.googleusercontent.com/-jJRhrcIcHUM/Tg_DN8y-EjE/AAAAAAAACPo/lsiTpH96VLc/s160-c/YumaTerritorialPrison.jpg",
   "title": "Yuma Territorial Prison",
   "date": "Mar 17, 2011",
   "photos": "41"},

  {"url": "/photographs/newzealand",
   "img": "https://lh5.googleusercontent.com/-oW8UPf3FnzY/Tg-9GrCI_ME/AAAAAAAACJ4/5xd_AI7lOL8/s160-c/NewZealandLOTRTourDay15.jpg",
   "title": "New Zealand",
   "date": "Jul 24, 2010",
   "albums": "17"}
];

generateAlbumThumbs(albums, "albums");
</script>

I obtained the thumbnail URLs for the albums from their Picasa pages by clicking on the "Link to this album" link that shows up on the right and copying and pasting the image URL into my code.  You can use any image you want for the thumbnail, but the generateAlbumThumb function currently expects the thumbnail to be 160x160 pixels.  

By the way, if you look at the thumbnail URLs that Picasa provides, you'll see that the URL component that comes right before the image filename contains text that says "s160-c".  The "s160" tells Picasa to scale the image to 160 pixels and the "-c" tells Picasa (I think) to crop the picture so that it is a 160x160 square.  You can change the size of any Picasa image displayed by a web browser simply by changing the value of the number that appears in the URL.  If a URL for a Picasa image does not already contain the scale command, you can just add it yourself and it will work.  This is a really cool feature of Picasa I think!

Enjoy!

Dustin

Hi, 

 

Thanks for this great example. 

I'm a little late to the party but thanks for the script it's what I've been looking for!  One question, does the multiple album script need to be inserted into the original embed script in place of other code or is it added along with the original embed code?  Thanks for the help!

Steve

Thanks for your example.  I really liked how it worked, but my customers has too many albums for the way you've manually created a list of albums.  With some more poking around with the API, I figured out how to get the list of galleries into your pattern.  To get the list of albums you have to an user query, base/user, with and ensure album data is returned, kind=album. 

    function loadPicasaAlbums(googleuserId) {
        $j = jQuery.noConflict();
        $j(document).ready(function() {
            $j.getJSON("https://picasaweb.google.com/data/feed/base/user/" + googleUserId + "?kind=album&alt=json-in-script&callback=?",
            function(data, status) {
                $j("#picasaTitle").text(data.feed.title.$t);
                $j("#picasaSubtitle").text(data.feed.subtitle.$t);
 
                $j.each(data.feed.entry, function(i, gallery) {
                    var thumb = gallery.media$group.media$thumbnail[0];
 
                    // Get the name of the gallery from the alternate link url.  Is this reliable?  Seems to work.
                    var textId = '';
                    $j.each(gallery.link, function(i, link) {
                        if (link.rel == 'alternate') {
                            var parts = link.href.split('/');
                            textId = parts[parts.length - 1];
                        }
                    });
 
                    $j('<a class="thumb" href="album.html?album=' + textId + '" title="' + gallery.title.$t + '" />')
                        .append($j('<img/>').attr('src', thumb.url))
                        .append('<span>' + gallery.title.$t + '</span>')
                        .appendTo('#gallery-links-container')
                    });
            });
        });
    }

 

enjoy,

jason

.  

Hi Jason,Wondering if you could help explain to me how I'd use your script, it sounds like it is exactly what I need but I'm a little out of my depth trying to use it. Thanks

This is fantastic and works great.  One question - how can I change the size of the thumbnails?  Thanks for the great code!

Did you get any answer?

Hi,


great job, thank you.


How can i do to have the album data variable?


If i update an album, i change the album data too.


I my website i would have this update date.


 


Thanks

It looks like the date on which the album was last updated is present within the same record that contains the picture data.  You should be able to access it within the getJSON() callback of the code as "data.feed.updated.$t".  It is a string formatted with the ISO 8601 time specification.  

Hello,

First of all, thank you for sharing with everybody that code, it really looks interesting and useful!

On the other hand, I'm not an expert programmer and I would like to ask you if there is the possibility to easily create a slideshow of the last updated pictures in Picasa Web Albums or a randomized slideshow of all the pictures in all the albums located under a picasa username and to embed it in the website. I'm looking for the code but can't find it, the only solution seems to be the blogger widget, but it's not a slideshow and only works with Blogger. And I don't know how to modify it to embed it in my website.

Thank you a lot for your attention!

Meritxell.

Hi,

 

I've been trying to make a web page for my spouse and started only 3 days ago. I knew nothing of HTML or JavaScript before. Now I know _next_ to nothing. But still I try. One thing I wanted to do is exactly what you have done. Transfer picture to Picasa and then embed the albums directly on the web page. I was REALLY happy to find your page! But now, probably because I know next to nothing, I can't seem to make it work. I first tried to copy and paste your code in an existing page I had. I got errors. I abandoned the idea after a few hours. But now I'm back trying and copied your code in a blank page. I still can't make it work. Of course, alot of my problems occur because I have to guess at what even the basic HTML codes mean or do so I often just copy codes at the wong place in my page. One error I got was on the line:

$j.getJSON("https://picasaweb.google.com/data/feed/base/user/" + userid + "/album/" + albumid + "?kind=photo&access=public&alt=json-in-script&callback=?"

I had the same problem even copying the generated link by Picasa for an album. For some reason, I had to modify that link (and yours) to the following:

$j.getJSON("https://picasaweb.google.com/data/feed/base/user/" + userid + "/album/" + albumid + "?kind=photo&amp;access=public&amp;alt=json-in-script&amp;callback=?"

That made the Picasa link work on my page. Don't ask me how I got that... I guess I looked at some other code where there was a & and saw amp; following it. In any case, when I enter the modification in your code, I still get an error but it's shown as if in the line:

.wrap("<a href=\"" + imgScaledUrl(photo.url, ps) + "\" title=\"" + desc + "\" />");

Now I can't see the problem, because I don't understand any of it and the problem might be somewhere before or after that line I guess but I was hoping that maybe you knew what the problem might be.

Embeding the albums would REALLY be great instead of having a new window open with Picasa. After that, I'll only have to learn how to put pictures and text exactly where I want them :) Maybe I'll even look do learn the stuff when I have a little more free time and maybe add a way to have people send a message to my spouse and have that embeded too. Then a shopping cart option with payment via PayPal. But then I don't have a few years to learn all that...

Hope you can help. Should you decide to take a look at my page, you'll see it's in french, but if you look at the top menu, you can go under "Voir Produits", then "Bracelets" then any color like "Rose". That will open the Picasa album and that's where I would like to have if embeded instead.

Many thanks,

Paul

Hi Paul,

Because you had to replace '&' with '&amp;', I suspect that you will also need to replace '<' with '&lt;' and '>' with '&gt;'.  I hope that gets you a little closer to your goal,

Dustin

On a scale of 1 to awesome, this script ranks awesome plus. Thanks for sharing!

I'm finding that captions that I add to Picasa images are getting truncated or missing if it they are longer than a few words. Any suggestions on how to get around this? If I can, it moves beyond the awesome scale. Thanks!

I think I solved my own problem (posted yesterday). Double quotes in the caption truncate the text following. I'm good!

Hi everybody and thank you very much for this great script.

I have followed all of the instructions, and the album actually shows, that's amazing! But, instead of opening the big images with slimbox effect it simply open a black window with the foto in it. Can anyone help me to understand where I did the mistake?

 

Thank you!!!!

 

Luca.

Hi Luca,

Slimbox needs to load some images and a CSS file to work correctly.  It is possible that these files are not being found.  

You can check your browser's JavaScript console to see if it is reporting any errors related to this issue.  Here are instructions for accessing the JavaScript console from different browsers: http://webmasters.stackexchange.com/questions/8525/how-to-open-the-javascript-console-in-different-browsers

Hi, your example has been very useful, thanks. I have modified it to use Google's cropping feature for thumbnails which returns nice square thumbnails of certain sizes... makes a grid look a bit nicer.

What I am struggling with is how to query by tag. It appears as though it might be a limitation of the json-in-script format. If I put '&tag=sometag' in the URL string, it doesn't return an 'entry' object when I have photos which do have that tag assigned to them. If I change it to 'alt=rss' or even 'alt=json-mobile', it returns the correct photos.

Any thoughts?

Thanks,

Jon.

Hi Jon,

Sorry, I can't be of much help here.  I haven't experimented with the tag query parameter before and am not really sure what the problem could be.

Dustin

Hi Jon,

Sounds like I'm having the same issue you did about putting together a nice grid of square thumbnails.

Can you please provide further details about how you accomplished this? I'm not familiar with Google's cropping feature for thumbnails.

 

Thanks very much.

Mike

 

First of all - fantastic script! Even for clicky-clicky-progammer as I'm easy to implement.

Just a quick question; the images open too large - you can't see the close button (in chrome & IE). Any idea how to adjust?

Thanks!
Michael

You can specify a size for the photograph displayed with slimbox as an optional argument to the loadPicasaAlbum function.  The full function signature is:

function loadPicasaAlbum(userid, albumid, thumbsize, photosize, margin)

The thumbsize argument specifies one of the three different sized thumbnails provided by Picasa.  Valid values are 0, 1, and 2.  Constants are defined for each size as:

var THUMB_SMALL = 0;

var THUMB_MEDIUM =1;

var TUMB_LARGE = 2;

The photosize specifies a width for the photo.  The photo will be scaled proportionally to the specfied width.  Three constants are defined for this value, but you can enter any size that you want.  The predefined sizes are:

var PHOTO_SMALL = 640;

var PHOTO_MEDIUM = 800;

var PHOTO_LARGE = 1024;

The defaults for both the thumb size and photo size are THUMB_MEDIUM and PHOTO_MEDIUM.  To use a smaller size, do something like this:

loadPicasaAlbum("myuserid", "myalbumid", THUMB_MEDIUM, 400);

Replace 400 with whatever size works best for the situation. 

Excellent script. Thank you..


Does this code work with dispalying VIDEOS uploaded on picasa? If not, whats the best way to acheive that?


Thanks

The script was only designed to work with Picasa photos.  According to the FAQ, Slimbox also only supports images.  I haven't looked at Picasa's video support, so am not sure what would need to be done to load video content.  Assuming it is possible to retrieve a list of video files from Picasa, you could modify the code to show the video thumbnails instead of photo thumbnails and replace Slimbox with somthing like Videobox.

Is it possible to display exif data below or beside individual photos?

This is possible.  It would be necessary to modify the function that is provided to $j.each() to add the code for displaying the EXIF data.  The function provided to $j.each() processes the metadata for each photo retrieved from Picasa to generate the HTML for displaying the thumbnail and creating the link for Slimbox.  The function could be altered to add HTML for displaying EXIF data with the photo.  If the metadata provided by Picasa doesn't contain the information that you are looking for, you would need to find a Javascript based solution to extracting EXIF data from an image file.  

I got it to work. It is great. To get exif data as json i replaced "feed" in the url with "api"

I got it to work. It is great. To get exif data as json i replaced "base" in the url with "api"

Fantastic Script, thank you for sharing.
Anyone know how to add a download link for hi-res photos whilst looking through the gallery?
Is this even possible with picasa?

Thanks for writing this interesting article. I like your website. I spent a couple hours implementing your script. I was surprised to see that it didnt' work. So after comparing with another article, I found out that I had to use /albumid/.... instead of just /album/....  in the link. Otherwise it's perfect.Thanks again.Bernard

Sorry, it's my mistake. I didn't realize I was passing an albumid instead of the album name. Your script requires the album name. So it's not a bug.