Andrew Hall


Scraping FFFFound.com for a digital photo frame

The Plan

A few years ago my girlfriend bought me a digital photo frame for Christmas. Since then, we have been on lots of holidays and have plenty of memories to display on the photo frame.

However, being the geek that I am, I decided I could put it to better use!

I love ffffound.com. If you’ve never heard of ffffound, it’s an image bookmarking site and always has some really interesting photos on there. I could waste literally hours looking at all the pictures on there (Ok I have wasted hours on there!). So I decided to make my digital photo frame display images from FFFFound!

I quickly thought of some criteria:

  • No images that are “too square” – It’s a waste of space on the digital photo frame (Which is 16:9)
  • No animated gifs – The Frame doesn’t support these!
  • No rude pictures – Not too bothered about this, but then I might have to explain why there’s a undraped woman on my photo frame!

I decided to use PHP to do this as I could knock something up really quickly:

for ($i=0;$i<3000;$i+=25){
$contents = file_get_contents("http://www.ffffound.com?offset=$i");
//find all images and not thumbnails
preg_match_all("/http:\/\/img\.(.*?)\" /smi",$contents,$match);
    foreach ($match[0] as $img){
	$img = substr($img,0,-2);
	$size = getimagesize($img);
	//if image isnt too square
	if ($size[0]-($size[0]*0.2)>$size[1]){
		//resize to a ration where the image will fit in the frame
		if ($size[0]/$size[1]>1.50){
			//resize to width
			$ratio = 720/$size[0];			
			//resize to height
			$ratio = 480/$size[1];	
		//resizing code
		$thumb = imagecreatetruecolor($size[0]*$ratio, $size[1]*$ratio);
		if (strcasecmp(substr($img,strrpos($img,".")),".jpg")==0){
			$source = imagecreatefromjpeg($img);
		if (strcasecmp(substr($img,strrpos($img,".")),".gif")==0){
			if (is_ani($img)){
			$source = imagecreatefromgif($img);
		if (strcasecmp(substr($img,strrpos($img,".")),".png")==0){
			$source = imagecreatefrompng($img);
		imagecopyresized($thumb, $source, 0, 0, 0, 0, $size[0]*$ratio, $size[1]*$ratio, $size[0], $size[1]);
		// Output
function is_ani($filename) {
    if(!($fh = @fopen($filename, 'rb')))
        return false;
    $count = 0;
    //an animated gif contains multiple "frames", with each frame having a 
    //header made up of:
    // * a static 4-byte sequence (\x00\x21\xF9\x04)
    // * 4 variable bytes
    // * a static 2-byte sequence (\x00\x2C) (some variants may use \x00\x21 ?)
    // We read through the file til we reach the end of the file, or we've found 
    // at least 2 frame headers
    while(!feof($fh) && $count < 2) {
        $chunk = fread($fh, 1024 * 100); //read 100kb at a time
        $count += preg_match_all('#\x00\x21\xF9\x04.{4}\x00(\x2C|\x21)#s', $chunk, $matches);
    return $count > 1;

Any updates will be on github

Note: I couldn’t do the nudity filter. It was possible but took far too long per image, so I decided to scrap it.


When I ran the script, and requested 3000 images, only 1216 met the criteria and took up 55 meg in total. I decided to to just use 10 meg worth, as this would find on the internal memory. – This is still more than 200 images. I have the frame set to change the image every hour, so this is fine for now and if I get bored, I can just scrape the site again for some fresh images.

Pictures: (From the actual frame in the dark)

FFFFound Example 1 on Andrew Hall's Blog FFFFound Example 2 on Andrew Hall's BlogFFFFound Example 2 on Andrew Hall's Blog

Overall I am really happy with how this went and I finally got round to using my digital photo frame too!

Disclaimer: This is meant for personal use only. I don’t encourage using the script to scrape pictures for any purpose other than to view the images.

1 Comment

  1. DJ hay |

    Yay google is my king aided me to uncover this wonderful internet site! .


Leave a comment or tweet me