I have been using Alexa services for thumbnails for sometime now, but have not been
happy with the processing time for site thumbnails for domains they don't have yet.
I recently came across a new thumbnail service provided by Shrink The Web
that seemed like a much better solution. It only took me a few minutes to switch over to it,
and so far it has been a superior solution to Alexa thumbnails.
I kind of beat them up over their sample code because it had a couple of minor errors
in it, and turned out to not be directly usable for me, and they asked to post what
I had, so here it is..
From playing with this, I now know xmax, ymax, embed, full, and scale all require an upgraded account.
The value embed=0 is for standard xml, embed=1 dumps raw jpg data, and embed=2 some java script.
Size is optional, and the value 'sm' is small, 'xlg' is x-large, any other value including 'lg' produces large.
Array
(
[Size] => xlg
[Url] => http://www.entraspan.com/blog/stw.html
[Service] => ShrinkWebUrlThumbnail
[Action] => Thumbnail
)
<?xml version="1.0" encoding="UTF-8"?>
<stw:ThumbnailResponse xmlns:stw="http://www.shrinktheweb.com/doc/stwresponse.xsd">
<stw:Response>
<stw:ThumbnailResult>
<stw:Thumbnail Exists="true">http://www.shrinktheweb.com/thumbs/d89g83938jfowic8/www.entraspan.com-320.jpg</stw:Thumbnail>
<stw:Thumbnail Verified="false">delivered</stw:Thumbnail>
</stw:ThumbnailResult>
<stw:SiteInfo>
<stw:Title><![CDATA[custom software development]]></stw:Title>
<stw:Description><![CDATA[]]></stw:Description>
</stw:SiteInfo>
<stw:ResponseStatus>
<stw:StatusCode>Success</stw:StatusCode>
</stw:ResponseStatus>
<stw:ResponseTimestamp>
<stw:StatusCode></stw:StatusCode>
</stw:ResponseTimestamp>
<stw:ResponseCode>
<stw:StatusCode>HTTP/1.1 200 OK</stw:StatusCode>
</stw:ResponseCode>
<stw:CategoryCode>
<stw:StatusCode>Not Yet Checked</stw:StatusCode>
</stw:CategoryCode>
</stw:Response>
</stw:ThumbnailResponse>
Direct Call Example http://www.shrinktheweb.com/thumbs/d89g83938jfowic8/www.entraspan.com-320.jpg
Cached Call Example /images/thumbnails/9462c2e45392cefede6245ca3cacd24b.jpg
Large Scaled Image /images/thumbnails/72dd23ba7306f66d77624fa52164ef37.jpg
Small Scaled Image /images/thumbnails/067e566c059b8b8d7f20eaaff98b5469.jpg
Scaled Image /images/thumbnails/7b83232f36a638e1d753f956f4583ece.jpg
Sample Source Code
<?php
/** * Sample of direct fetch for remote use. */
$url = "http://www.entraspan.com/blog/stw.html";
$args["Size"] = "xlg";
if (isset($_POST["Size"]) && $_POST["Size"]) $args["Size"] = $_POST["Size"]; if (isset($_POST["xmax"]) && $_POST["xmax"]) $args["xmax"] = $_POST["xmax"]; if (isset($_POST["ymax"]) && $_POST["ymax"]) $args["ymax"] = $_POST["ymax"]; if (isset($_POST["scale"]) && $_POST["scale"]) $args["scale"] = $_POST["scale"]; if (isset($_POST["full"]) && $_POST["full"]) $args["full"] = 1; if (isset($_POST["embed"]) && $_POST["embed"]) $args["embed"] = $_POST["embed"];
function showImage($label, $src) { echo "<h3>$label</h3>";
if ($src) { // The extra ? is so our servers bypass varnish, a reverse proxy echo "<p><a href=$src?><img src=$src?></a>"; echo "<br style=font-size:9px><a href=$src>$src</a>"; } else ; // use some default image }
showImage("Direct Call Example", AppSTW::queryRemoteThumbnail($url, $args, true)); showImage("Cached Call Example", AppSTW::getThumbnail($url, $args)); showImage("Large Scaled Image", AppSTW::getLargeThumbnail($url, true, true)); showImage("Small Scaled Image", AppSTW::getSmallThumbnail($url, true, true)); showImage("Scaled Image", AppSTW::getScaledThumbnail($url, 640, 480));
?>
|
The AppSTW Class File
<?php
/** * Implements sourcing thumbnails from http://www.shrinktheweb.com * * Dependent on PHP5, but could be easily back-ported. All config * information is defined in constants. No reason to ever create * an instance of this class, hence abstract. * * @author Entraspan, Based in part on STW sample code * @copyright Open Source/Creative Commons */ abstract class AppSTW { const ACCESS_KEY = "your key"; const SECRET_KEY = "your user"; const THUMBNAIL_URI = "/images/thumbnails"; const THUMBNAIL_DIR = "/static"; const CACHE_DAYS = 3; // used 7 for Alexa!
private static function make_http_request($url){ $lines = file($url); return implode("", $lines); }
/** * Calls through the API and processes the results based on the * original sample code from STW. This function is public for * example only. It really should not be used since thumbnails * should be cached locally using getThumbnail. * * It is common for this routine to return a null value when the * thumbnail does not yet exist and is queued up for processing. * * @param string $url URL to get thumbnail for * @param array $args Array of parameters to use * @return string full remote URL to the thumbnail */ public static function queryRemoteThumbnail($url, $args = null, $debug = false) { $args = is_array($args) ? $args : array(); $args["Url"] = $url;
$defaults["Service"] = "ShrinkWebUrlThumbnail"; $defaults["Action"] = "Thumbnail"; $defaults["STWAccessKeyId"] = self::ACCESS_KEY; $defaults["u"] = self::SECRET_KEY;
foreach ($defaults as $k=>$v) if (!isset($args[$k])) $args[$k] = $v;
$request_url = "http://www.shrinktheweb.com/xino.php?".http_build_query($args);
$line = self::make_http_request($request_url);
if ($debug) { echo '<pre style=font-size:10px>'; unset($args["STWAccessKeyId"]); unset($args["u"]); print_r($args); echo '</pre>'; echo '<div style=font-size:10px>'; highlight_string($line); echo '</div>'; }
$regex = '/<[^:]*:Thumbnail\\s*(?:Exists=\"((?:true)|(?:false))\")?[^>]*>([^<]*)<\//';
if (preg_match($regex, $line, $matches) == 1 && $matches[1] == "true") return $matches[2];
return null; }
/** * Refreshes the thumbnail if it is expired or creates it if it does * not exist. There is no cleanup of the thumbnails for ones that don't * get used again, e.g. find /static/images/thumbnails -type f -mtime +7 -delete * * Every combination of url and call arguments results in a unique filename * through a MD5 hash. The size argument can also be an array where you can * add any parameter you wish to the request, or override any default. * * It is up to the calling function to decide what to do with the results when * a null is returned. I often store the src in a database with a timestamp so * that I do not bombard the server with repeated requests for a thumbnail that * doesn't yet exist, although STW is very fast at processing. * * @param string $url URL to get thumbnail for * @param array $args Array of parameters to use * @param boolean $force Force call to bypass cache, was used for debugging * @return string Local SRC URI for the thumbnail. */ public static function getThumbnail($url, $args = null, $force = false) { $args = $args ? $args : array("Size"=>"lg"); $name = md5($url.serialize($args)).".jpg"; $src = self::THUMBNAIL_URI."/$name"; $path = self::THUMBNAIL_DIR.$src; $cutoff = time() - 3600 * 24 * self::CACHE_DAYS;
if ($force || !file_exists($path) || filemtime($path) <= $cutoff) if (($jpgurl = self::queryRemoteThumbnail($url, $args))) if (($im = imagecreatefromjpeg($jpgurl))) imagejpeg($im, $path, 100);
if (file_exists($path)) return $src;
return null; }
/** * Always retrieves the X-Large thumbnail from STW, then uses * local gd library to create arbitrary sized thumbnails. * * By passing the same arguments used for small/large should * generate cache hits so the only size every retrieved would * be xlg. * * @param string $url URL to get thumbnail for * @param string $width The desired image width * @param string $height The desired image height * @param string $args Used to make name same as sm/lg fetches. */ public static function getScaledThumbnail($url, $width, $height, $args = null, $force) { $args = $args ? $args : array("width"=>$width, "height"=>$height); $name = md5($url.serialize($args)).".jpg"; $src = self::THUMBNAIL_URI."/$name"; $path = self::THUMBNAIL_DIR.$src; $cutoff = time() - 3600 * 24 * self::CACHE_DAYS;
if ($force || !file_exists($path) || filemtime($path) <= $cutoff) if (($xlg = self::getXLargeThumbnail($url))) if (($im = imagecreatefromjpeg(self::THUMBNAIL_DIR.$xlg))) { list($xw, $xh) = getimagesize(self::THUMBNAIL_DIR.$xlg); $scaled = imagecreatetruecolor($width, $height);
if (imagecopyresampled($scaled, $im, 0, 0, 0, 0, $width, $height, $xw, $xh)) imagejpeg($scaled, $path, 100); }
if (file_exists($path)) return $src;
return null; }
/** * Convenience Function for 320x240 * * @param string $url URL to get thumbnail for */ public static function getXLargeThumbnail($url) { return self::getThumbnail($url, array("Size"=>"xlg")); }
/** * Convenience Function for 200x150 * * @param string $url URL to get thumbnail for * @param boolean $scaler Scale image from xlg */ public static function getLargeThumbnail($url, $scaler = true, $force = false) { if ($scaler) return self::getScaledThumbnail($url, 200, 150, array("Size"=>"lg"), $force);
return self::getThumbnail($url); }
/** * Convenience Function for 120x90 * * @param string $url URL to get thumbnail for * @param boolean $scaler Scale image from xlg */ public static function getSmallThumbnail($url, $scaler = true, $force = false) { if ($scaler) return self::getScaledThumbnail($url, 120, 90, array("Size"=>"sm"), $force);
return self::getThumbnail($url, array("Size"=>"sm")); } }
?>
|
|