Wednesday, 13 August 2008
Photo Breadcrumbs
I have started geotagging my Flickr photos when appropriate. It got me wondering if I could use the geotags to act as a breadcrumb trail to see where I had been.
So last night I knocked up a quick mashup between Flickr and Google maps to put markers on the map for each photo and then draw a line between each photo in order of date taken. You can then browse the trail to see where I have been. Great for virtual stalkers.
My [non-existent] javascript skills have failed me to do anything more advanced but maybe when I get some time I will be able to add 'next' and 'previous' buttons so you can 'walk' the path of photos.
See the breadcrumb trail.
Has anyone does this properly anywhere?
Saturday, 28 June 2008
Create a Flickr Tag Cloud in PHP
Here is a very basic way of creating a Flickr tag cloud in PHP. To make the Flickr API calls simple I have used phpFlickr.
The what and the why are listed below but there is a worked example available also.
I am going to use these variables in the code:
$reqtags = 150; // Number of tags to display
$user = "xrrr"; // Flickr user to search for tags
$min_font = "10"; // Font size to start drawing tags
$max_font = "30"; // The maximum font size tags can get
$user = "xrrr"; // Flickr user to search for tags
$min_font = "10"; // Font size to start drawing tags
$max_font = "30"; // The maximum font size tags can get
First of all we need to convert the username string into a Flickr User ID. To do this use the flickr.people.findByUsername API function:
$ns = $f->people_findByUsername($user);
$nsid = $ns[nsid];
$nsid = $ns[nsid];
Then we obtain the tags from Flickr using the flickr.tags.getListUserPopular API function which returns an array of tags. The phpFlickr object will return an array of arrays. Each array contains the tag value and the count of the number of times the tag is used. We store the number of tags by counting the size of the array and sort the array by the tag count value:
$tags = $f->tags_getListUserPopular ($nsid, $reqtags);
$numtags = count ($tags);
sort ($tags);
$numtags = count ($tags);
sort ($tags);
We now calculate the number of tags that should be displayed at each font size. To do this we just divide the number of tags by the number of font sizes available (maximum font minus the minimum font) and round it down to the nearest whole number. Note if there are more font sizes than tags (in this example the user has less than 20 tags) then the interval will be zero. This is ok.
$increment = intval($numtags/($max_font-$min_font));
In order to calculate the font sizes we loop though the tag list (which is in tag count order) and create an associative array of "tag_name => font_size". This code is basic so does not attempt to calculate the font size from the tag count. It just loops through the array and every time the interval value is reached it increments the font size. If the interval value is zero then it just increments the font size for every tag.
$size = $min_font ;
for ($i=0; $i < $numtags; $i++) {
$output[$tags[$i][_content]] = $size ;
if ($increment == 0 || $i % $increment == 0 )
$size++;
}
}
for ($i=0; $i < $numtags; $i++) {
$output[$tags[$i][_content]] = $size ;
if ($increment == 0 || $i % $increment == 0 )
$size++;
}
}
We now have an associative array of tag and font size ordered by tag frequency. Tag clouds tend to be in alphabetical order so we sort by the associative array keys using the PHP function ksort:
ksort($output);
Finally we print out the HTML to build the tag cloud and link back to Flickr:
$url = "http://www.flickr.com/photos/$user/tags/" ;
echo "<div id='TagCloud'>";
foreach ($output as $tg => $sz) {
echo " <a href='".$url.$tg."' style='font-size: ".$sz."px;'>".$tg."</a> \n" ;
}
echo "</div>";
echo "<div id='TagCloud'>";
foreach ($output as $tg => $sz) {
echo " <a href='".$url.$tg."' style='font-size: ".$sz."px;'>".$tg."</a> \n" ;
}
echo "</div>";
The resultant HTML can be styled with the following style sheet to make it look like Flickr:
<style>
body {
font-family:Arial,Helvetica,sans-serif;
}
#TagCloud {
background:#F5F5F5 none repeat scroll 0%;
border:1px solid #EEEEEE;
padding:15px;
}
#TagCloud a {
text-decoration:none;
}
#TagCloud a:link {
color:#0063DC;
}
#TagCloud a:visited {
color:#0063DC;
}
#TagCloud a:hover {
background:#0063DC none repeat scroll 0% 0%;
color:#FFFFFF;
text-decoration:none;
}
</style>
body {
font-family:Arial,Helvetica,sans-serif;
}
#TagCloud {
background:#F5F5F5 none repeat scroll 0%;
border:1px solid #EEEEEE;
padding:15px;
}
#TagCloud a {
text-decoration:none;
}
#TagCloud a:link {
color:#0063DC;
}
#TagCloud a:visited {
color:#0063DC;
}
#TagCloud a:hover {
background:#0063DC none repeat scroll 0% 0%;
color:#FFFFFF;
text-decoration:none;
}
</style>
I have created a working example to demonstrate the code and make it easier to reuse.
Tuesday, 3 June 2008
Groopy Search by Group Update
Today I have created a new 'advanced' search page that allows you to search for your photos in a particular group.
Click the 'advanced search' link on the front page or bookmark this link.
Monday, 2 June 2008
Groopy Performance Update
I released version 0.2 of Flickr Groopy today. Aside from some code tidy ups the main updates are:
- I found out that you can obtain the number of views of a photo from the search meaning that I can bypass one of the slow API calls. It now takes half the time to render a screen of images. Simply add 'extras=>views' into the request for flickr.photos.search and it means that the flickr.photos.getInfo call can be missed out entirely
- I have changed the sort order to sort by 'relevance' rather than 'interestingness-desc' - I will be making the sort order a user option at some point
Wednesday, 28 May 2008
Flickr Groopy
I have released the first cut of my pet mini-project that I have called Flickr Groopy.
Flickr Groopy exists because of a set of Flickr Groups called Views 25 through to Views 25000. The idea is that once one of your photos reaches 25 views you can add it into the Views 25 group. As soon as your photo reaches 50 views you remove it from the Views 25 group and add it into the Views 50 group and so on.
The group rules state that a single photo should only ever be in one Views nn group at a time. The Flickr GUI is a bit clunky for swapping pictures between groups quickly so I decided to learn PHP, CSS and the Flickr API to create a tool for viewing your photos, highlighting the photos that are eligible for promotion into the next group and providing a one click update of the groups that the photo is in.
The result was Flickr Groopy:
How it works:
Based on a search string the code uses the flickr.photos.search API call to get a list of the user's photos that match the search criteria.
For each photo in the response:
- Call flickr.photos.getInfo to get the number of views
- Call flickr.photos.getAllContexts to get the groups the photo is in
- Find out if the photo is already in a Views nn group
- Using the number of views and group list work out if the photo is in the correct group
- If the photo could be added to a Views nn group then highlight the photo
It is all implemented with HTML DIV elements and some CSS fun powered by PHP and phpFlickr behind the scenes.
Current features:
- Text search for a user's photos
- Grid display (restricted to 16 pics for performance) of the output
- Colour coded highlighting of pictures eligible for moving groups
- One click group update for eligible pictures
Planned features:
- Search for user's photos already in a Views group
- Tag cloud to inspire searches
- Search by Flickr set
- Notification of photos existing in more than one group with one click fix
- Support for the sister Faves set of groups
Known problems with the current version:
- Internet Explorer does not render CSS the same as Firefox and Safari so I need to work out how to get the CSS to look the same on all three browsers
- The drawing is quite slow - I have added some timing trace to the code and it shows that almost 0.6 seconds per picture is taken up with two Flickr API calls. There is not much I can do about this I am afraid. I am investigating whether I can make the calls in parallel to speed things up a bit but that involves Ajax threading and is a bit scary!
- The page should draw before it attempts to do the lengthy photo processing - working on a prototype Ajax version of the grid rendering
- There is a 1 second pause between clicking on an image and anything happening - also clicking on multiple pictures breaks the UI slightly as update responses get lost - need a wait icon and a way to disable additional clicks whilst a response is pending
Flickr Groopy is here: xrrr.co.uk/groopy
Subscribe to:
Posts (Atom)