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

  1. <?php
  2. /*
  3. * Compressor
  4. *
  5. * PunyPNG.com image compression API wrapper
  6. * Supports PNG, JPEG, and GIF images
  7. *
  8. * @author Ben LeMasurier <ben@sparkfun.com>
  9. *
  10. */
  11. namespace SparkLib\Image;
  12. class Compressor
  13. {
  14. const URL = 'http://www.punypng.com/api/optimize';
  15. const DOWNLOAD_URL = 'http://www.punypng.com/processor/download_image';
  16. const MAX_FILESIZE = 5242880; // PunyPNG limit, 5MB.
  17. private $_ch;
  18. public function __construct()
  19. {
  20. // PunyPNG API key must be defined
  21. if(!defined('PUNYPNG_KEY'))
  22. throw new \Exception('PunyPNG API key undefined');
  23. // ensure curl library is available
  24. if(!function_exists('curl_version'))
  25. throw new \Exception('cURL library support is required');
  26. // initialize curl
  27. $this->_ch = curl_init(self::URL);
  28. }
  29. public function __destruct()
  30. {
  31. curl_close($this->_ch);
  32. }
  33. /*
  34. * upload and compress the given file
  35. *
  36. * @param $file - full path to uncompressed image
  37. * @param $lossy - defaults to false, lossless and lossy formats
  38. * will still be availbe, this is only for logging purposes.
  39. * @return mixed, false on failure
  40. */
  41. public function compress($file, $lossy = false)
  42. {
  43. if(!file_exists($file))
  44. throw new \Exception('File not found: ' . $file);
  45. if(!is_file($file))
  46. throw new \Exception('Invalid file: ' . $file);
  47. if(filesize($file) > self::MAX_FILESIZE)
  48. throw new \Exception($file . ' exceeds maximum file size of ' . self::MAX_FILESIZE . ' bytes');
  49. $result = $this->upload($file);
  50. if(!$result->status)
  51. return false;
  52. if(!isset($result->optimized_url))
  53. throw new \Exception('PunyPNG API did not return a download URL');
  54. if($lossy && !isset($result->indexed_url))
  55. throw new \Exception('PunyPNG API did not return a lossy download URL');
  56. // Log successful result
  57. $ics = new \ImageCompressionSaurus();
  58. $ics->original_size = $result->original_size;
  59. if($lossy)
  60. $ics->optimized_size = ($result->original_size - $result->indexed_savings_bytes);
  61. else
  62. $ics->optimized_size = $result->optimized_size;
  63. $ics->ctime = \SparkLib\DB::Now();
  64. $ics->insert();
  65. return $result;
  66. }
  67. /*
  68. * download the optimized image
  69. *
  70. * @param $file mixed - this can either be the url
  71. * or the return value from compress()
  72. * @param $save_path - full save path for the downloaded image
  73. * @param $lossy boolean - if passing the result of compress(), specify
  74. * whether you'd like the lossy or lossless image. Defaults to false.
  75. */
  76. public function download($file, $save_path, $lossy = false)
  77. {
  78. if(!is_string($file)) {
  79. if($lossy) {
  80. if(!isset($file->indexed_url))
  81. throw new \Exception('missing indexed download url');
  82. $file = $file->indexed_url;
  83. } else {
  84. if(!isset($file->optimized_url))
  85. throw new \Exception('missing optimized download url');
  86. $file = $file->optimized_url;
  87. }
  88. }
  89. curl_setopt($this->_ch, CURLOPT_URL, $file);
  90. curl_setopt($this->_ch, CURLOPT_RETURNTRANSFER, true);
  91. curl_setopt($this->_ch, CURLOPT_FILE, fopen($save_path, 'w'));
  92. return curl_exec($this->_ch);
  93. }
  94. /*
  95. * upload the given file to PunyPNG for compression
  96. *
  97. * @return mixed - PunyPNG API Response and status code
  98. */
  99. private function upload($file)
  100. {
  101. $postdata = [
  102. 'key' => PUNYPNG_KEY,
  103. 'img' => new \CURLFile($file)
  104. ];
  105. curl_setopt($this->_ch, CURLOPT_URL, self::URL);
  106. curl_setopt($this->_ch, CURLOPT_POST, true);
  107. curl_setopt($this->_ch, CURLOPT_POSTFIELDS, $postdata);
  108. curl_setopt($this->_ch, CURLOPT_RETURNTRANSFER, true);
  109. $result = json_decode(curl_exec($this->_ch));
  110. $result->status = (curl_getinfo($this->_ch, CURLINFO_HTTP_CODE) === 200);
  111. return $result;
  112. }
  113. }