A modest collection of PHP libraries used at SparkFun.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

138 lines
3.8 KiB

<?php
/*
* Compressor
*
* PunyPNG.com image compression API wrapper
* Supports PNG, JPEG, and GIF images
*
* @author Ben LeMasurier <ben@sparkfun.com>
*
*/
namespace SparkLib\Image;
class Compressor
{
const URL = 'http://www.punypng.com/api/optimize';
const DOWNLOAD_URL = 'http://www.punypng.com/processor/download_image';
const MAX_FILESIZE = 5242880; // PunyPNG limit, 5MB.
private $_ch;
public function __construct()
{
// PunyPNG API key must be defined
if(!defined('PUNYPNG_KEY'))
throw new \Exception('PunyPNG API key undefined');
// ensure curl library is available
if(!function_exists('curl_version'))
throw new \Exception('cURL library support is required');
// initialize curl
$this->_ch = curl_init(self::URL);
}
public function __destruct()
{
curl_close($this->_ch);
}
/*
* upload and compress the given file
*
* @param $file - full path to uncompressed image
* @param $lossy - defaults to false, lossless and lossy formats
* will still be availbe, this is only for logging purposes.
* @return mixed, false on failure
*/
public function compress($file, $lossy = false)
{
if(!file_exists($file))
throw new \Exception('File not found: ' . $file);
if(!is_file($file))
throw new \Exception('Invalid file: ' . $file);
if(filesize($file) > self::MAX_FILESIZE)
throw new \Exception($file . ' exceeds maximum file size of ' . self::MAX_FILESIZE . ' bytes');
$result = $this->upload($file);
if(!$result->status)
return false;
if(!isset($result->optimized_url))
throw new \Exception('PunyPNG API did not return a download URL');
if($lossy && !isset($result->indexed_url))
throw new \Exception('PunyPNG API did not return a lossy download URL');
// Log successful result
$ics = new \ImageCompressionSaurus();
$ics->original_size = $result->original_size;
if($lossy)
$ics->optimized_size = ($result->original_size - $result->indexed_savings_bytes);
else
$ics->optimized_size = $result->optimized_size;
$ics->ctime = \SparkLib\DB::Now();
$ics->insert();
return $result;
}
/*
* download the optimized image
*
* @param $file mixed - this can either be the url
* or the return value from compress()
* @param $save_path - full save path for the downloaded image
* @param $lossy boolean - if passing the result of compress(), specify
* whether you'd like the lossy or lossless image. Defaults to false.
*/
public function download($file, $save_path, $lossy = false)
{
if(!is_string($file)) {
if($lossy) {
if(!isset($file->indexed_url))
throw new \Exception('missing indexed download url');
$file = $file->indexed_url;
} else {
if(!isset($file->optimized_url))
throw new \Exception('missing optimized download url');
$file = $file->optimized_url;
}
}
curl_setopt($this->_ch, CURLOPT_URL, $file);
curl_setopt($this->_ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($this->_ch, CURLOPT_FILE, fopen($save_path, 'w'));
return curl_exec($this->_ch);
}
/*
* upload the given file to PunyPNG for compression
*
* @return mixed - PunyPNG API Response and status code
*/
private function upload($file)
{
$postdata = [
'key' => PUNYPNG_KEY,
'img' => new \CURLFile($file)
];
curl_setopt($this->_ch, CURLOPT_URL, self::URL);
curl_setopt($this->_ch, CURLOPT_POST, true);
curl_setopt($this->_ch, CURLOPT_POSTFIELDS, $postdata);
curl_setopt($this->_ch, CURLOPT_RETURNTRANSFER, true);
$result = json_decode(curl_exec($this->_ch));
$result->status = (curl_getinfo($this->_ch, CURLINFO_HTTP_CODE) === 200);
return $result;
}
}