You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
183 lines
4.7 KiB
PHTML
183 lines
4.7 KiB
PHTML
11 months ago
|
<?php
|
||
|
/*
|
||
|
* (c) Our Code World <dev@ourcodeworld.com>
|
||
|
*
|
||
|
* This source file is subject to the MIT license that is bundled
|
||
|
* with this source code in the file LICENSE.
|
||
|
*/
|
||
|
|
||
|
class PNGQuant {
|
||
|
private $binaryPath = "pngquant";
|
||
|
|
||
|
private $imagePath = "";
|
||
|
|
||
|
private $options = array();
|
||
|
|
||
|
/**
|
||
|
* The error table is based in the pngquant_error enum of the official library
|
||
|
* @see https://github.com/pornel/pngquant/blob/8eebc5702df6901cff71062fc616c4441bfeb48f/rwpng.h#L47
|
||
|
*/
|
||
|
private $_errorTable = array(
|
||
|
"0" => "SUCCESS",
|
||
|
"1" => "MISSING_ARGUMENT",
|
||
|
"2" => "READ_ERROR",
|
||
|
"4" => "INVALID_ARGUMENT",
|
||
|
"15" => "NOT_OVERWRITING_ERROR",
|
||
|
"16" => "CANT_WRITE_ERROR",
|
||
|
"17" => "OUT_OF_MEMORY_ERROR",
|
||
|
"18" => "WRONG_ARCHITECTURE", // Missing SSE
|
||
|
"24" => "PNG_OUT_OF_MEMORY_ERROR",
|
||
|
"25" => "LIBPNG_FATAL_ERROR",
|
||
|
"26" => "WRONG_INPUT_COLOR_TYPE",
|
||
|
"35" => "LIBPNG_INIT_ERROR",
|
||
|
"98" => "TOO_LARGE_FILE",
|
||
|
"99" => "TOO_LOW_QUALITY"
|
||
|
);
|
||
|
|
||
|
public function __construct(){
|
||
|
|
||
|
}
|
||
|
|
||
|
public function setBinaryPath($pathToBinary){
|
||
|
$this->binaryPath = escapeshellarg($pathToBinary);
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
public function setOption($key, $value = null , $space = false, $isPath = false){
|
||
|
$length_options = count($this->options);
|
||
|
|
||
|
// Overwrite an option if it was already set
|
||
|
for($i = 0; $i < $length_options; ++$i){
|
||
|
$existent_option = $this->options[$i];
|
||
|
|
||
|
if($key == $existent_option["key"]){
|
||
|
array_splice($this->options, $i, 1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
array_push($this->options, array(
|
||
|
'key' => $key,
|
||
|
'value' => $value,
|
||
|
'space' => $space,
|
||
|
'isPath' => $isPath
|
||
|
));
|
||
|
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
public function buildCommand(){
|
||
|
$command = $this->binaryPath. " ". $this->imagePath;
|
||
|
foreach($this->options as $option){
|
||
|
$key = $option['key'];
|
||
|
$value = $option['value'];
|
||
|
$space = $option['space'];
|
||
|
$isPath = $option['isPath'];
|
||
|
|
||
|
if(!$value){
|
||
|
$command .= " $key";
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if($isPath){
|
||
|
$value = escapeshellarg($value);
|
||
|
}
|
||
|
|
||
|
if($space){
|
||
|
$command .= " $key $value";
|
||
|
}else{
|
||
|
$command .= " $key=$value";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $command;
|
||
|
}
|
||
|
|
||
|
/** END console utility wrapper **/
|
||
|
|
||
|
/** Start wrapper **/
|
||
|
public function disableDithering(){
|
||
|
return $this->setOption('--nofs');
|
||
|
}
|
||
|
|
||
|
public function getErrorTable(){
|
||
|
return $this->_errorTable;
|
||
|
}
|
||
|
|
||
|
public function setImage($imagePath){
|
||
|
$this->imagePath = $imagePath;
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
public function setCustomExtension($extension){
|
||
|
return $this->setOption('--ext',$extension, true, true);
|
||
|
}
|
||
|
|
||
|
public function setDitheringLevel($level){
|
||
|
return $this->setOption('--floyd', $level);
|
||
|
}
|
||
|
|
||
|
public function skipIfLarger(){
|
||
|
return $this->setOption('--skip-if-larger');
|
||
|
}
|
||
|
|
||
|
public function setQuality($minQuality = 60, $maxQuality = 80){
|
||
|
return $this->setOption('--quality', "$minQuality-$maxQuality", true);
|
||
|
}
|
||
|
|
||
|
public function setOutputImage($imagePath){
|
||
|
return $this->setOption('--output', $imagePath, true, true);
|
||
|
}
|
||
|
|
||
|
public function setSpeed($speed){
|
||
|
return $this->setOption('--speed', $speed, true);
|
||
|
}
|
||
|
|
||
|
public function overwriteExistingFile(){
|
||
|
return $this->setOption('--force');
|
||
|
}
|
||
|
|
||
|
public function posterize($value){
|
||
|
return $this->setOption('--posterize', $value);
|
||
|
}
|
||
|
|
||
|
public function removeMetadata(){
|
||
|
return $this->setOption('--strip');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Run the built command
|
||
|
*/
|
||
|
public function execute(){
|
||
|
$consoleInstruction = $this->buildCommand();
|
||
|
$output = null;
|
||
|
|
||
|
system($consoleInstruction, $output);
|
||
|
|
||
|
return $output;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Execute PNGQUANT with the providen commands and retrieve the generated image
|
||
|
* directly into a variable
|
||
|
*/
|
||
|
public function getRawOutput(){
|
||
|
// Create a temporal file in the system
|
||
|
$fileName = uniqid() . '.png';
|
||
|
$tempFile = tempnam(Zc::C('temp.dir'), $fileName);
|
||
|
|
||
|
// Set the output path the tmp file
|
||
|
$this->setOutputImage($tempFile);
|
||
|
|
||
|
$consoleInstruction = $this->buildCommand();
|
||
|
$output = null;
|
||
|
system($consoleInstruction, $output);
|
||
|
$imageData = file_get_contents($tempFile);
|
||
|
unlink($tempFile);
|
||
|
|
||
|
return array(
|
||
|
'statusCode' => $output,
|
||
|
'imageData' => $imageData
|
||
|
);
|
||
|
}
|
||
|
}
|