mirror of
https://github.com/mosbth/cimage.git
synced 2025-09-10 07:30:41 +02:00
Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
c4d3f7cdf6 | ||
|
a50aab9d8e | ||
|
de942268c9 | ||
|
d8090e7531 | ||
|
c94027a752 | ||
|
2959f11f33 | ||
|
cf8bb8973d | ||
|
d8db2b9105 | ||
|
b65b420313 |
213
CAsciiArt.php
Normal file
213
CAsciiArt.php
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Create an ASCII version of an image.
|
||||||
|
* Inspired by https://gist.github.com/donatj/1353237 and various sources.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class CAsciiArt
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Character set to use.
|
||||||
|
*/
|
||||||
|
private $characterSet = array(
|
||||||
|
'one' => "#0XT|:,.' ",
|
||||||
|
'two' => "@%#*+=-:. ",
|
||||||
|
'three' => "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. "
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current character set.
|
||||||
|
*/
|
||||||
|
private $characters = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Length of current character set.
|
||||||
|
*/
|
||||||
|
private $charCount = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scale of the area to swap to a character.
|
||||||
|
*/
|
||||||
|
private $scale = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strategy to calculate luminance.
|
||||||
|
*/
|
||||||
|
private $luminanceStrategy = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor which sets default options.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->setOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a custom character set.
|
||||||
|
*
|
||||||
|
* @param string $key for the character set.
|
||||||
|
* @param string $value for the character set.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function addCharacterSet($key, $value)
|
||||||
|
{
|
||||||
|
$this->characterSet[$key] = $value;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Length of current character set.
|
||||||
|
*
|
||||||
|
* @param array $options to use as default settings.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setOptions($options = array())
|
||||||
|
{
|
||||||
|
$default = array(
|
||||||
|
"characterSet" => 'two',
|
||||||
|
"scale" => 14,
|
||||||
|
"luminanceStrategy" => 3,
|
||||||
|
"customCharacterSet" => null,
|
||||||
|
);
|
||||||
|
$default = array_merge($default, $options);
|
||||||
|
|
||||||
|
if (!is_null($default['customCharacterSet'])) {
|
||||||
|
$this->addCharacterSet('custom', $default['customCharacterSet']);
|
||||||
|
$default['characterSet'] = 'custom';
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->scale = $default['scale'];
|
||||||
|
$this->characters = $this->characterSet[$default['characterSet']];
|
||||||
|
$this->charCount = strlen($this->characters);
|
||||||
|
$this->luminanceStrategy = $default['luminanceStrategy'];
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an Ascii image from an image file.
|
||||||
|
*
|
||||||
|
* @param string $filename of the image to use.
|
||||||
|
*
|
||||||
|
* @return string $ascii with the ASCII image.
|
||||||
|
*/
|
||||||
|
public function createFromFile($filename)
|
||||||
|
{
|
||||||
|
$img = imagecreatefromstring(file_get_contents($filename));
|
||||||
|
list($width, $height) = getimagesize($filename);
|
||||||
|
|
||||||
|
$ascii = null;
|
||||||
|
$incY = $this->scale;
|
||||||
|
$incX = $this->scale / 2;
|
||||||
|
|
||||||
|
for ($y = 0; $y < $height - 1; $y += $incY) {
|
||||||
|
for ($x = 0; $x < $width - 1; $x += $incX) {
|
||||||
|
$toX = min($x + $this->scale / 2, $width - 1);
|
||||||
|
$toY = min($y + $this->scale, $height - 1);
|
||||||
|
$luminance = $this->luminanceAreaAverage($img, $x, $y, $toX, $toY);
|
||||||
|
$ascii .= $this->luminance2character($luminance);
|
||||||
|
}
|
||||||
|
$ascii .= PHP_EOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ascii;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the luminance from a region of an image using average color value.
|
||||||
|
*
|
||||||
|
* @param string $img the image.
|
||||||
|
* @param integer $x1 the area to get pixels from.
|
||||||
|
* @param integer $y1 the area to get pixels from.
|
||||||
|
* @param integer $x2 the area to get pixels from.
|
||||||
|
* @param integer $y2 the area to get pixels from.
|
||||||
|
*
|
||||||
|
* @return integer $luminance with a value between 0 and 100.
|
||||||
|
*/
|
||||||
|
public function luminanceAreaAverage($img, $x1, $y1, $x2, $y2)
|
||||||
|
{
|
||||||
|
$numPixels = ($x2 - $x1 + 1) * ($y2 - $y1 + 1);
|
||||||
|
$luminance = 0;
|
||||||
|
|
||||||
|
for ($x = $x1; $x <= $x2; $x++) {
|
||||||
|
for ($y = $y1; $y <= $y2; $y++) {
|
||||||
|
$rgb = imagecolorat($img, $x, $y);
|
||||||
|
$red = (($rgb >> 16) & 0xFF);
|
||||||
|
$green = (($rgb >> 8) & 0xFF);
|
||||||
|
$blue = ($rgb & 0xFF);
|
||||||
|
$luminance += $this->getLuminance($red, $green, $blue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $luminance / $numPixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate luminance value with different strategies.
|
||||||
|
*
|
||||||
|
* @param integer $red The color red.
|
||||||
|
* @param integer $green The color green.
|
||||||
|
* @param integer $blue The color blue.
|
||||||
|
*
|
||||||
|
* @return float $luminance with a value between 0 and 1.
|
||||||
|
*/
|
||||||
|
public function getLuminance($red, $green, $blue)
|
||||||
|
{
|
||||||
|
switch($this->luminanceStrategy) {
|
||||||
|
case 1:
|
||||||
|
$luminance = ($red * 0.2126 + $green * 0.7152 + $blue * 0.0722) / 255;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
$luminance = ($red * 0.299 + $green * 0.587 + $blue * 0.114) / 255;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
$luminance = sqrt(0.299 * pow($red, 2) + 0.587 * pow($green, 2) + 0.114 * pow($blue, 2)) / 255;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
default:
|
||||||
|
$luminance = ($red + $green + $blue) / (255 * 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $luminance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translate the luminance value to a character.
|
||||||
|
*
|
||||||
|
* @param string $position a value between 0-100 representing the
|
||||||
|
* luminance.
|
||||||
|
*
|
||||||
|
* @return string with the ascii character.
|
||||||
|
*/
|
||||||
|
public function luminance2character($luminance)
|
||||||
|
{
|
||||||
|
$position = (int) round($luminance * ($this->charCount - 1));
|
||||||
|
$char = $this->characters[$position];
|
||||||
|
return $char;
|
||||||
|
}
|
||||||
|
}
|
43
CHttpGet.php
43
CHttpGet.php
@@ -21,6 +21,33 @@ class CHttpGet
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build an encoded url.
|
||||||
|
*
|
||||||
|
* @param string $baseUrl This is the original url which will be merged.
|
||||||
|
* @param string $merge Thse parts should be merged into the baseUrl,
|
||||||
|
* the format is as parse_url.
|
||||||
|
*
|
||||||
|
* @return string $url as the modified url.
|
||||||
|
*/
|
||||||
|
public function buildUrl($baseUrl, $merge)
|
||||||
|
{
|
||||||
|
$parts = parse_url($baseUrl);
|
||||||
|
$parts = array_merge($parts, $merge);
|
||||||
|
|
||||||
|
$url = $parts['scheme'];
|
||||||
|
$url .= "://";
|
||||||
|
$url .= $parts['host'];
|
||||||
|
$url .= isset($parts['port'])
|
||||||
|
? ":" . $parts['port']
|
||||||
|
: "" ;
|
||||||
|
$url .= $parts['path'];
|
||||||
|
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the url for the request.
|
* Set the url for the request.
|
||||||
*
|
*
|
||||||
@@ -30,6 +57,18 @@ class CHttpGet
|
|||||||
*/
|
*/
|
||||||
public function setUrl($url)
|
public function setUrl($url)
|
||||||
{
|
{
|
||||||
|
$parts = parse_url($url);
|
||||||
|
|
||||||
|
$path = "";
|
||||||
|
if (isset($parts['path'])) {
|
||||||
|
$pathParts = explode('/', $parts['path']);
|
||||||
|
unset($pathParts[0]);
|
||||||
|
foreach ($pathParts as $value) {
|
||||||
|
$path .= "/" . rawurlencode($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$url = $this->buildUrl($url, array("path" => $path));
|
||||||
|
|
||||||
$this->request['url'] = $url;
|
$this->request['url'] = $url;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@@ -93,6 +132,8 @@ class CHttpGet
|
|||||||
*
|
*
|
||||||
* @param boolean $debug set to true to dump headers.
|
* @param boolean $debug set to true to dump headers.
|
||||||
*
|
*
|
||||||
|
* @throws Exception when curl fails to retrieve url.
|
||||||
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function doGet($debug = false)
|
public function doGet($debug = false)
|
||||||
@@ -115,7 +156,7 @@ class CHttpGet
|
|||||||
$response = curl_exec($ch);
|
$response = curl_exec($ch);
|
||||||
|
|
||||||
if (!$response) {
|
if (!$response) {
|
||||||
return false;
|
throw new Exception("Failed retrieving url, details follows: " . curl_error($ch));
|
||||||
}
|
}
|
||||||
|
|
||||||
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
|
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
|
||||||
|
43
CImage.php
43
CImage.php
@@ -334,6 +334,13 @@ class CImage
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* output to ascii can take som options as an array.
|
||||||
|
*/
|
||||||
|
private $asciiOptions = array();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Properties, the class is mutable and the method setOptions()
|
* Properties, the class is mutable and the method setOptions()
|
||||||
* decides (partly) what properties are created.
|
* decides (partly) what properties are created.
|
||||||
@@ -2250,6 +2257,10 @@ class CImage
|
|||||||
header('Content-type: application/json');
|
header('Content-type: application/json');
|
||||||
echo $this->json($file);
|
echo $this->json($file);
|
||||||
exit;
|
exit;
|
||||||
|
} elseif ($format == 'ascii') {
|
||||||
|
header('Content-type: text/plain');
|
||||||
|
echo $this->ascii($file);
|
||||||
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->log("Outputting image: $file");
|
$this->log("Outputting image: $file");
|
||||||
@@ -2341,6 +2352,38 @@ class CImage
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set options for creating ascii version of image.
|
||||||
|
*
|
||||||
|
* @param array $options empty to use default or set options to change.
|
||||||
|
*
|
||||||
|
* @return void.
|
||||||
|
*/
|
||||||
|
public function setAsciiOptions($options = array())
|
||||||
|
{
|
||||||
|
$this->asciiOptions = $options;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an ASCII version from the image details.
|
||||||
|
*
|
||||||
|
* @param string $file the file to output.
|
||||||
|
*
|
||||||
|
* @return string ASCII representation of the image.
|
||||||
|
*/
|
||||||
|
public function ascii($file = null)
|
||||||
|
{
|
||||||
|
$file = $file ? $file : $this->cacheFileName;
|
||||||
|
|
||||||
|
$asciiArt = new CAsciiArt();
|
||||||
|
$asciiArt->setOptions($this->asciiOptions);
|
||||||
|
return $asciiArt->createFromFile($file);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log an event if verbose mode.
|
* Log an event if verbose mode.
|
||||||
*
|
*
|
||||||
|
@@ -147,7 +147,7 @@ class CRemoteImage
|
|||||||
*/
|
*/
|
||||||
public function setHeaderFields()
|
public function setHeaderFields()
|
||||||
{
|
{
|
||||||
$this->http->setHeader("User-Agent", "CImage/0.7.0 (PHP/". phpversion() . " cURL)");
|
$this->http->setHeader("User-Agent", "CImage/0.7.2 (PHP/". phpversion() . " cURL)");
|
||||||
$this->http->setHeader("Accept", "image/jpeg,image/png,image/gif");
|
$this->http->setHeader("Accept", "image/jpeg,image/png,image/gif");
|
||||||
|
|
||||||
if ($this->useCache) {
|
if ($this->useCache) {
|
||||||
@@ -226,6 +226,8 @@ class CRemoteImage
|
|||||||
*
|
*
|
||||||
* @param string $url a remote url.
|
* @param string $url a remote url.
|
||||||
*
|
*
|
||||||
|
* @throws Exception when status code does not match 200 or 304.
|
||||||
|
*
|
||||||
* @return string as path to downloaded file or false if failed.
|
* @return string as path to downloaded file or false if failed.
|
||||||
*/
|
*/
|
||||||
public function download($url)
|
public function download($url)
|
||||||
@@ -258,7 +260,7 @@ class CRemoteImage
|
|||||||
return $this->updateCacheDetails();
|
return $this->updateCacheDetails();
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
throw new Exception("Unknown statuscode when downloading remote image: " . $this->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
14
README.md
14
README.md
@@ -37,7 +37,7 @@ Requirements
|
|||||||
Installation
|
Installation
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
|
||||||
There are two ways of installing. You either install the whole project which uses the autoloader to include the various files, or you install the all-included bundle that -- for convenience -- contains all code in one script.
|
There are several ways of installing. You either install the whole project which uses the autoloader to include the various files, or you install the all-included bundle that -- for convenience -- contains all code in one script.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -45,14 +45,14 @@ There are two ways of installing. You either install the whole project which use
|
|||||||
|
|
||||||
The [sourcode is available on GitHub](https://github.com/mosbth/cimage). Clone, fork or [download as zip](https://github.com/mosbth/cimage/archive/master.zip).
|
The [sourcode is available on GitHub](https://github.com/mosbth/cimage). Clone, fork or [download as zip](https://github.com/mosbth/cimage/archive/master.zip).
|
||||||
|
|
||||||
**Latest stable version is v0.7.0 released 2015-02-10.**
|
**Latest stable version is v0.7.1 released 2015-07-25.**
|
||||||
|
|
||||||
I prefer cloning like this. Do switch to the latest stable version.
|
I prefer cloning like this. Do switch to the latest stable version.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone git://github.com/mosbth/cimage.git
|
git clone git://github.com/mosbth/cimage.git
|
||||||
cd cimage
|
cd cimage
|
||||||
git checkout v0.7.0
|
git checkout v0.7.1
|
||||||
```
|
```
|
||||||
|
|
||||||
Make the cache-directory writable by the webserver.
|
Make the cache-directory writable by the webserver.
|
||||||
@@ -75,13 +75,19 @@ There are some all-included bundles of `img.php` that can be downloaded and used
|
|||||||
Dowload the version of your choice like this.
|
Dowload the version of your choice like this.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
wget https://github.com/mosbth/cimage/tree/v0.7.0/webroot/imgp.php
|
wget https://github.com/mosbth/cimage/tree/v0.7.1/webroot/imgp.php
|
||||||
```
|
```
|
||||||
|
|
||||||
Open up the file in your editor and edit the array `$config`. Ensure that the paths to the image directory and the cache directory matches your environment, or create an own config-file for the script.
|
Open up the file in your editor and edit the array `$config`. Ensure that the paths to the image directory and the cache directory matches your environment, or create an own config-file for the script.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
###Install from Packagist
|
||||||
|
|
||||||
|
You can install the package [`mos/cimage` from Packagist](https://packagist.org/packages/mos/cimage) using composer.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Use cases
|
Use cases
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
|
||||||
|
12
REVISION.md
12
REVISION.md
@@ -5,6 +5,18 @@ Revision history
|
|||||||
[](https://scrutinizer-ci.com/g/mosbth/cimage/build-status/master)
|
[](https://scrutinizer-ci.com/g/mosbth/cimage/build-status/master)
|
||||||
|
|
||||||
|
|
||||||
|
v0.7.3 (2015-09-01)
|
||||||
|
-------------------------------------
|
||||||
|
|
||||||
|
* Support output of ascii images, #67.
|
||||||
|
|
||||||
|
|
||||||
|
v0.7.2 (2015-08-17)
|
||||||
|
-------------------------------------
|
||||||
|
|
||||||
|
* Allow space in remote filenames, fix #98.
|
||||||
|
|
||||||
|
|
||||||
v0.7.1 (2015-07-25)
|
v0.7.1 (2015-07-25)
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
|
@@ -37,6 +37,7 @@ $ECHO "\n webroot/img_header.php"
|
|||||||
$ECHO "\n CHttpGet.php"
|
$ECHO "\n CHttpGet.php"
|
||||||
$ECHO "\n CRemoteImage.php"
|
$ECHO "\n CRemoteImage.php"
|
||||||
$ECHO "\n CWhitelist.php"
|
$ECHO "\n CWhitelist.php"
|
||||||
|
$ECHO "\n CAsciiArt.php"
|
||||||
$ECHO "\n CImage.php"
|
$ECHO "\n CImage.php"
|
||||||
$ECHO "\n webroot/img.php"
|
$ECHO "\n webroot/img.php"
|
||||||
$ECHO "\n"
|
$ECHO "\n"
|
||||||
@@ -64,10 +65,13 @@ $ECHO "$NEWLINES" | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
|||||||
tail -n +2 CRemoteImage.php | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
tail -n +2 CRemoteImage.php | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
||||||
$ECHO "$NEWLINES" | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
$ECHO "$NEWLINES" | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
||||||
|
|
||||||
tail -n +2 CImage.php | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
tail -n +2 CWhitelist.php | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
||||||
$ECHO "$NEWLINES" | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
$ECHO "$NEWLINES" | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
||||||
|
|
||||||
tail -n +2 CWhitelist.php | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
tail -n +2 CAsciiArt.php | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
||||||
|
$ECHO "$NEWLINES" | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
||||||
|
|
||||||
|
tail -n +2 CImage.php | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
||||||
$ECHO "$NEWLINES" | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
$ECHO "$NEWLINES" | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
||||||
|
|
||||||
tail -n +2 webroot/img.php | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
tail -n +2 webroot/img.php | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
||||||
|
@@ -8,12 +8,12 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$version = "v0.7.1 (2015-07-25)";
|
$version = "v0.7.3 (2015-09-01)";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default configuration options, can be overridden in own config-file.
|
* Display error message.
|
||||||
*
|
*
|
||||||
* @param string $msg to display.
|
* @param string $msg to display.
|
||||||
*
|
*
|
||||||
@@ -754,11 +754,51 @@ verbose("filters = " . print_r($filters, 1));
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* json - output the image as a JSON object with details on the image.
|
* json - output the image as a JSON object with details on the image.
|
||||||
|
* ascii - output the image as ASCII art.
|
||||||
*/
|
*/
|
||||||
$outputFormat = getDefined('json', 'json', null);
|
$outputFormat = getDefined('json', 'json', null);
|
||||||
|
$outputFormat = getDefined('ascii', 'ascii', $outputFormat);
|
||||||
|
|
||||||
|
verbose("outputformat = $outputFormat");
|
||||||
|
|
||||||
|
if ($outputFormat == 'ascii') {
|
||||||
|
$defaultOptions = getConfig(
|
||||||
|
'ascii-options',
|
||||||
|
array(
|
||||||
|
"characterSet" => 'two',
|
||||||
|
"scale" => 14,
|
||||||
|
"luminanceStrategy" => 3,
|
||||||
|
"customCharacterSet" => null,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$options = get('ascii');
|
||||||
|
$options = explode(',', $options);
|
||||||
|
|
||||||
|
if (isset($options[0]) && !empty($options[0])) {
|
||||||
|
$defaultOptions['characterSet'] = $options[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($options[1]) && !empty($options[1])) {
|
||||||
|
$defaultOptions['scale'] = $options[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($options[2]) && !empty($options[2])) {
|
||||||
|
$defaultOptions['luminanceStrategy'] = $options[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($options) > 3) {
|
||||||
|
// Last option is custom character string
|
||||||
|
unset($options[0]);
|
||||||
|
unset($options[1]);
|
||||||
|
unset($options[2]);
|
||||||
|
$characterString = implode($options);
|
||||||
|
$defaultOptions['customCharacterSet'] = $characterString;
|
||||||
|
}
|
||||||
|
|
||||||
|
$img->setAsciiOptions($defaultOptions);
|
||||||
|
}
|
||||||
|
|
||||||
verbose("json = $outputFormat");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -299,4 +299,25 @@ return array(
|
|||||||
'golden' => 1.618,
|
'golden' => 1.618,
|
||||||
);
|
);
|
||||||
},*/
|
},*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* default options for ascii image.
|
||||||
|
*
|
||||||
|
* Default values as specified below in the array.
|
||||||
|
* ascii-options:
|
||||||
|
* characterSet: Choose any character set available in CAsciiArt.
|
||||||
|
* scale: How many pixels should each character
|
||||||
|
* translate to.
|
||||||
|
* luminanceStrategy: Choose any strategy available in CAsciiArt.
|
||||||
|
* customCharacterSet: Define your own character set.
|
||||||
|
*/
|
||||||
|
/*'ascii-options' => array(
|
||||||
|
"characterSet" => 'two',
|
||||||
|
"scale" => 14,
|
||||||
|
"luminanceStrategy" => 3,
|
||||||
|
"customCharacterSet" => null,
|
||||||
|
);
|
||||||
|
},*/
|
||||||
);
|
);
|
||||||
|
483
webroot/imgd.php
483
webroot/imgd.php
@@ -58,6 +58,33 @@ class CHttpGet
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build an encoded url.
|
||||||
|
*
|
||||||
|
* @param string $baseUrl This is the original url which will be merged.
|
||||||
|
* @param string $merge Thse parts should be merged into the baseUrl,
|
||||||
|
* the format is as parse_url.
|
||||||
|
*
|
||||||
|
* @return string $url as the modified url.
|
||||||
|
*/
|
||||||
|
public function buildUrl($baseUrl, $merge)
|
||||||
|
{
|
||||||
|
$parts = parse_url($baseUrl);
|
||||||
|
$parts = array_merge($parts, $merge);
|
||||||
|
|
||||||
|
$url = $parts['scheme'];
|
||||||
|
$url .= "://";
|
||||||
|
$url .= $parts['host'];
|
||||||
|
$url .= isset($parts['port'])
|
||||||
|
? ":" . $parts['port']
|
||||||
|
: "" ;
|
||||||
|
$url .= $parts['path'];
|
||||||
|
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the url for the request.
|
* Set the url for the request.
|
||||||
*
|
*
|
||||||
@@ -67,6 +94,18 @@ class CHttpGet
|
|||||||
*/
|
*/
|
||||||
public function setUrl($url)
|
public function setUrl($url)
|
||||||
{
|
{
|
||||||
|
$parts = parse_url($url);
|
||||||
|
|
||||||
|
$path = "";
|
||||||
|
if (isset($parts['path'])) {
|
||||||
|
$pathParts = explode('/', $parts['path']);
|
||||||
|
unset($pathParts[0]);
|
||||||
|
foreach ($pathParts as $value) {
|
||||||
|
$path .= "/" . rawurlencode($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$url = $this->buildUrl($url, array("path" => $path));
|
||||||
|
|
||||||
$this->request['url'] = $url;
|
$this->request['url'] = $url;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@@ -130,6 +169,8 @@ class CHttpGet
|
|||||||
*
|
*
|
||||||
* @param boolean $debug set to true to dump headers.
|
* @param boolean $debug set to true to dump headers.
|
||||||
*
|
*
|
||||||
|
* @throws Exception when curl fails to retrieve url.
|
||||||
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function doGet($debug = false)
|
public function doGet($debug = false)
|
||||||
@@ -152,7 +193,7 @@ class CHttpGet
|
|||||||
$response = curl_exec($ch);
|
$response = curl_exec($ch);
|
||||||
|
|
||||||
if (!$response) {
|
if (!$response) {
|
||||||
return false;
|
throw new Exception("Failed retrieving url, details follows: " . curl_error($ch));
|
||||||
}
|
}
|
||||||
|
|
||||||
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
|
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
|
||||||
@@ -435,7 +476,7 @@ class CRemoteImage
|
|||||||
*/
|
*/
|
||||||
public function setHeaderFields()
|
public function setHeaderFields()
|
||||||
{
|
{
|
||||||
$this->http->setHeader("User-Agent", "CImage/0.7.0 (PHP/". phpversion() . " cURL)");
|
$this->http->setHeader("User-Agent", "CImage/0.7.2 (PHP/". phpversion() . " cURL)");
|
||||||
$this->http->setHeader("Accept", "image/jpeg,image/png,image/gif");
|
$this->http->setHeader("Accept", "image/jpeg,image/png,image/gif");
|
||||||
|
|
||||||
if ($this->useCache) {
|
if ($this->useCache) {
|
||||||
@@ -514,6 +555,8 @@ class CRemoteImage
|
|||||||
*
|
*
|
||||||
* @param string $url a remote url.
|
* @param string $url a remote url.
|
||||||
*
|
*
|
||||||
|
* @throws Exception when status code does not match 200 or 304.
|
||||||
|
*
|
||||||
* @return string as path to downloaded file or false if failed.
|
* @return string as path to downloaded file or false if failed.
|
||||||
*/
|
*/
|
||||||
public function download($url)
|
public function download($url)
|
||||||
@@ -546,7 +589,7 @@ class CRemoteImage
|
|||||||
return $this->updateCacheDetails();
|
return $this->updateCacheDetails();
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
throw new Exception("Unknown statuscode when downloading remote image: " . $this->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -597,6 +640,285 @@ class CRemoteImage
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Act as whitelist (or blacklist).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class CWhitelist
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Array to contain the whitelist options.
|
||||||
|
*/
|
||||||
|
private $whitelist = array();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the whitelist from an array of strings, each item in the
|
||||||
|
* whitelist should be a regexp without the surrounding / or #.
|
||||||
|
*
|
||||||
|
* @param array $whitelist with all valid options,
|
||||||
|
* default is to clear the whitelist.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function set($whitelist = array())
|
||||||
|
{
|
||||||
|
if (!is_array($whitelist)) {
|
||||||
|
throw new Exception("Whitelist is not of a supported format.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->whitelist = $whitelist;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if item exists in the whitelist.
|
||||||
|
*
|
||||||
|
* @param string $item string to check.
|
||||||
|
* @param array $whitelist optional with all valid options, default is null.
|
||||||
|
*
|
||||||
|
* @return boolean true if item is in whitelist, else false.
|
||||||
|
*/
|
||||||
|
public function check($item, $whitelist = null)
|
||||||
|
{
|
||||||
|
if ($whitelist !== null) {
|
||||||
|
$this->set($whitelist);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($item) or empty($this->whitelist)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->whitelist as $regexp) {
|
||||||
|
if (preg_match("#$regexp#", $item)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an ASCII version of an image.
|
||||||
|
* Inspired by https://gist.github.com/donatj/1353237 and various sources.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class CAsciiArt
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Character set to use.
|
||||||
|
*/
|
||||||
|
private $characterSet = array(
|
||||||
|
'one' => "#0XT|:,.' ",
|
||||||
|
'two' => "@%#*+=-:. ",
|
||||||
|
'three' => "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. "
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current character set.
|
||||||
|
*/
|
||||||
|
private $characters = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Length of current character set.
|
||||||
|
*/
|
||||||
|
private $charCount = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scale of the area to swap to a character.
|
||||||
|
*/
|
||||||
|
private $scale = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strategy to calculate luminance.
|
||||||
|
*/
|
||||||
|
private $luminanceStrategy = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor which sets default options.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->setOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a custom character set.
|
||||||
|
*
|
||||||
|
* @param string $key for the character set.
|
||||||
|
* @param string $value for the character set.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function addCharacterSet($key, $value)
|
||||||
|
{
|
||||||
|
$this->characterSet[$key] = $value;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Length of current character set.
|
||||||
|
*
|
||||||
|
* @param array $options to use as default settings.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setOptions($options = array())
|
||||||
|
{
|
||||||
|
$default = array(
|
||||||
|
"characterSet" => 'two',
|
||||||
|
"scale" => 14,
|
||||||
|
"luminanceStrategy" => 3,
|
||||||
|
"customCharacterSet" => null,
|
||||||
|
);
|
||||||
|
$default = array_merge($default, $options);
|
||||||
|
|
||||||
|
if (!is_null($default['customCharacterSet'])) {
|
||||||
|
$this->addCharacterSet('custom', $default['customCharacterSet']);
|
||||||
|
$default['characterSet'] = 'custom';
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->scale = $default['scale'];
|
||||||
|
$this->characters = $this->characterSet[$default['characterSet']];
|
||||||
|
$this->charCount = strlen($this->characters);
|
||||||
|
$this->luminanceStrategy = $default['luminanceStrategy'];
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an Ascii image from an image file.
|
||||||
|
*
|
||||||
|
* @param string $filename of the image to use.
|
||||||
|
*
|
||||||
|
* @return string $ascii with the ASCII image.
|
||||||
|
*/
|
||||||
|
public function createFromFile($filename)
|
||||||
|
{
|
||||||
|
$img = imagecreatefromstring(file_get_contents($filename));
|
||||||
|
list($width, $height) = getimagesize($filename);
|
||||||
|
|
||||||
|
$ascii = null;
|
||||||
|
$incY = $this->scale;
|
||||||
|
$incX = $this->scale / 2;
|
||||||
|
|
||||||
|
for ($y = 0; $y < $height - 1; $y += $incY) {
|
||||||
|
for ($x = 0; $x < $width - 1; $x += $incX) {
|
||||||
|
$toX = min($x + $this->scale / 2, $width - 1);
|
||||||
|
$toY = min($y + $this->scale, $height - 1);
|
||||||
|
$luminance = $this->luminanceAreaAverage($img, $x, $y, $toX, $toY);
|
||||||
|
$ascii .= $this->luminance2character($luminance);
|
||||||
|
}
|
||||||
|
$ascii .= PHP_EOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ascii;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the luminance from a region of an image using average color value.
|
||||||
|
*
|
||||||
|
* @param string $img the image.
|
||||||
|
* @param integer $x1 the area to get pixels from.
|
||||||
|
* @param integer $y1 the area to get pixels from.
|
||||||
|
* @param integer $x2 the area to get pixels from.
|
||||||
|
* @param integer $y2 the area to get pixels from.
|
||||||
|
*
|
||||||
|
* @return integer $luminance with a value between 0 and 100.
|
||||||
|
*/
|
||||||
|
public function luminanceAreaAverage($img, $x1, $y1, $x2, $y2)
|
||||||
|
{
|
||||||
|
$numPixels = ($x2 - $x1 + 1) * ($y2 - $y1 + 1);
|
||||||
|
$luminance = 0;
|
||||||
|
|
||||||
|
for ($x = $x1; $x <= $x2; $x++) {
|
||||||
|
for ($y = $y1; $y <= $y2; $y++) {
|
||||||
|
$rgb = imagecolorat($img, $x, $y);
|
||||||
|
$red = (($rgb >> 16) & 0xFF);
|
||||||
|
$green = (($rgb >> 8) & 0xFF);
|
||||||
|
$blue = ($rgb & 0xFF);
|
||||||
|
$luminance += $this->getLuminance($red, $green, $blue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $luminance / $numPixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate luminance value with different strategies.
|
||||||
|
*
|
||||||
|
* @param integer $red The color red.
|
||||||
|
* @param integer $green The color green.
|
||||||
|
* @param integer $blue The color blue.
|
||||||
|
*
|
||||||
|
* @return float $luminance with a value between 0 and 1.
|
||||||
|
*/
|
||||||
|
public function getLuminance($red, $green, $blue)
|
||||||
|
{
|
||||||
|
switch($this->luminanceStrategy) {
|
||||||
|
case 1:
|
||||||
|
$luminance = ($red * 0.2126 + $green * 0.7152 + $blue * 0.0722) / 255;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
$luminance = ($red * 0.299 + $green * 0.587 + $blue * 0.114) / 255;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
$luminance = sqrt(0.299 * pow($red, 2) + 0.587 * pow($green, 2) + 0.114 * pow($blue, 2)) / 255;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
default:
|
||||||
|
$luminance = ($red + $green + $blue) / (255 * 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $luminance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translate the luminance value to a character.
|
||||||
|
*
|
||||||
|
* @param string $position a value between 0-100 representing the
|
||||||
|
* luminance.
|
||||||
|
*
|
||||||
|
* @return string with the ascii character.
|
||||||
|
*/
|
||||||
|
public function luminance2character($luminance)
|
||||||
|
{
|
||||||
|
$position = (int) round($luminance * ($this->charCount - 1));
|
||||||
|
$char = $this->characters[$position];
|
||||||
|
return $char;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resize and crop images on the fly, store generated images in a cache.
|
* Resize and crop images on the fly, store generated images in a cache.
|
||||||
*
|
*
|
||||||
@@ -932,6 +1254,13 @@ class CImage
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* output to ascii can take som options as an array.
|
||||||
|
*/
|
||||||
|
private $asciiOptions = array();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Properties, the class is mutable and the method setOptions()
|
* Properties, the class is mutable and the method setOptions()
|
||||||
* decides (partly) what properties are created.
|
* decides (partly) what properties are created.
|
||||||
@@ -2848,6 +3177,10 @@ class CImage
|
|||||||
header('Content-type: application/json');
|
header('Content-type: application/json');
|
||||||
echo $this->json($file);
|
echo $this->json($file);
|
||||||
exit;
|
exit;
|
||||||
|
} elseif ($format == 'ascii') {
|
||||||
|
header('Content-type: text/plain');
|
||||||
|
echo $this->ascii($file);
|
||||||
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->log("Outputting image: $file");
|
$this->log("Outputting image: $file");
|
||||||
@@ -2939,6 +3272,38 @@ class CImage
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set options for creating ascii version of image.
|
||||||
|
*
|
||||||
|
* @param array $options empty to use default or set options to change.
|
||||||
|
*
|
||||||
|
* @return void.
|
||||||
|
*/
|
||||||
|
public function setAsciiOptions($options = array())
|
||||||
|
{
|
||||||
|
$this->asciiOptions = $options;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an ASCII version from the image details.
|
||||||
|
*
|
||||||
|
* @param string $file the file to output.
|
||||||
|
*
|
||||||
|
* @return string ASCII representation of the image.
|
||||||
|
*/
|
||||||
|
public function ascii($file = null)
|
||||||
|
{
|
||||||
|
$file = $file ? $file : $this->cacheFileName;
|
||||||
|
|
||||||
|
$asciiArt = new CAsciiArt();
|
||||||
|
$asciiArt->setOptions($this->asciiOptions);
|
||||||
|
return $asciiArt->createFromFile($file);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log an event if verbose mode.
|
* Log an event if verbose mode.
|
||||||
*
|
*
|
||||||
@@ -3028,70 +3393,6 @@ EOD;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Act as whitelist (or blacklist).
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class CWhitelist
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Array to contain the whitelist options.
|
|
||||||
*/
|
|
||||||
private $whitelist = array();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the whitelist from an array of strings, each item in the
|
|
||||||
* whitelist should be a regexp without the surrounding / or #.
|
|
||||||
*
|
|
||||||
* @param array $whitelist with all valid options,
|
|
||||||
* default is to clear the whitelist.
|
|
||||||
*
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function set($whitelist = array())
|
|
||||||
{
|
|
||||||
if (!is_array($whitelist)) {
|
|
||||||
throw new Exception("Whitelist is not of a supported format.");
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->whitelist = $whitelist;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if item exists in the whitelist.
|
|
||||||
*
|
|
||||||
* @param string $item string to check.
|
|
||||||
* @param array $whitelist optional with all valid options, default is null.
|
|
||||||
*
|
|
||||||
* @return boolean true if item is in whitelist, else false.
|
|
||||||
*/
|
|
||||||
public function check($item, $whitelist = null)
|
|
||||||
{
|
|
||||||
if ($whitelist !== null) {
|
|
||||||
$this->set($whitelist);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty($item) or empty($this->whitelist)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($this->whitelist as $regexp) {
|
|
||||||
if (preg_match("#$regexp#", $item)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resize and crop images on the fly, store generated images in a cache.
|
* Resize and crop images on the fly, store generated images in a cache.
|
||||||
*
|
*
|
||||||
@@ -3101,12 +3402,12 @@ class CWhitelist
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$version = "v0.7.1 (2015-07-25)";
|
$version = "v0.7.3 (2015-09-01)";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default configuration options, can be overridden in own config-file.
|
* Display error message.
|
||||||
*
|
*
|
||||||
* @param string $msg to display.
|
* @param string $msg to display.
|
||||||
*
|
*
|
||||||
@@ -3847,11 +4148,51 @@ verbose("filters = " . print_r($filters, 1));
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* json - output the image as a JSON object with details on the image.
|
* json - output the image as a JSON object with details on the image.
|
||||||
|
* ascii - output the image as ASCII art.
|
||||||
*/
|
*/
|
||||||
$outputFormat = getDefined('json', 'json', null);
|
$outputFormat = getDefined('json', 'json', null);
|
||||||
|
$outputFormat = getDefined('ascii', 'ascii', $outputFormat);
|
||||||
|
|
||||||
|
verbose("outputformat = $outputFormat");
|
||||||
|
|
||||||
|
if ($outputFormat == 'ascii') {
|
||||||
|
$defaultOptions = getConfig(
|
||||||
|
'ascii-options',
|
||||||
|
array(
|
||||||
|
"characterSet" => 'two',
|
||||||
|
"scale" => 14,
|
||||||
|
"luminanceStrategy" => 3,
|
||||||
|
"customCharacterSet" => null,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$options = get('ascii');
|
||||||
|
$options = explode(',', $options);
|
||||||
|
|
||||||
|
if (isset($options[0]) && !empty($options[0])) {
|
||||||
|
$defaultOptions['characterSet'] = $options[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($options[1]) && !empty($options[1])) {
|
||||||
|
$defaultOptions['scale'] = $options[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($options[2]) && !empty($options[2])) {
|
||||||
|
$defaultOptions['luminanceStrategy'] = $options[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($options) > 3) {
|
||||||
|
// Last option is custom character string
|
||||||
|
unset($options[0]);
|
||||||
|
unset($options[1]);
|
||||||
|
unset($options[2]);
|
||||||
|
$characterString = implode($options);
|
||||||
|
$defaultOptions['customCharacterSet'] = $characterString;
|
||||||
|
}
|
||||||
|
|
||||||
|
$img->setAsciiOptions($defaultOptions);
|
||||||
|
}
|
||||||
|
|
||||||
verbose("json = $outputFormat");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
483
webroot/imgp.php
483
webroot/imgp.php
@@ -58,6 +58,33 @@ class CHttpGet
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build an encoded url.
|
||||||
|
*
|
||||||
|
* @param string $baseUrl This is the original url which will be merged.
|
||||||
|
* @param string $merge Thse parts should be merged into the baseUrl,
|
||||||
|
* the format is as parse_url.
|
||||||
|
*
|
||||||
|
* @return string $url as the modified url.
|
||||||
|
*/
|
||||||
|
public function buildUrl($baseUrl, $merge)
|
||||||
|
{
|
||||||
|
$parts = parse_url($baseUrl);
|
||||||
|
$parts = array_merge($parts, $merge);
|
||||||
|
|
||||||
|
$url = $parts['scheme'];
|
||||||
|
$url .= "://";
|
||||||
|
$url .= $parts['host'];
|
||||||
|
$url .= isset($parts['port'])
|
||||||
|
? ":" . $parts['port']
|
||||||
|
: "" ;
|
||||||
|
$url .= $parts['path'];
|
||||||
|
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the url for the request.
|
* Set the url for the request.
|
||||||
*
|
*
|
||||||
@@ -67,6 +94,18 @@ class CHttpGet
|
|||||||
*/
|
*/
|
||||||
public function setUrl($url)
|
public function setUrl($url)
|
||||||
{
|
{
|
||||||
|
$parts = parse_url($url);
|
||||||
|
|
||||||
|
$path = "";
|
||||||
|
if (isset($parts['path'])) {
|
||||||
|
$pathParts = explode('/', $parts['path']);
|
||||||
|
unset($pathParts[0]);
|
||||||
|
foreach ($pathParts as $value) {
|
||||||
|
$path .= "/" . rawurlencode($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$url = $this->buildUrl($url, array("path" => $path));
|
||||||
|
|
||||||
$this->request['url'] = $url;
|
$this->request['url'] = $url;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@@ -130,6 +169,8 @@ class CHttpGet
|
|||||||
*
|
*
|
||||||
* @param boolean $debug set to true to dump headers.
|
* @param boolean $debug set to true to dump headers.
|
||||||
*
|
*
|
||||||
|
* @throws Exception when curl fails to retrieve url.
|
||||||
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function doGet($debug = false)
|
public function doGet($debug = false)
|
||||||
@@ -152,7 +193,7 @@ class CHttpGet
|
|||||||
$response = curl_exec($ch);
|
$response = curl_exec($ch);
|
||||||
|
|
||||||
if (!$response) {
|
if (!$response) {
|
||||||
return false;
|
throw new Exception("Failed retrieving url, details follows: " . curl_error($ch));
|
||||||
}
|
}
|
||||||
|
|
||||||
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
|
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
|
||||||
@@ -435,7 +476,7 @@ class CRemoteImage
|
|||||||
*/
|
*/
|
||||||
public function setHeaderFields()
|
public function setHeaderFields()
|
||||||
{
|
{
|
||||||
$this->http->setHeader("User-Agent", "CImage/0.7.0 (PHP/". phpversion() . " cURL)");
|
$this->http->setHeader("User-Agent", "CImage/0.7.2 (PHP/". phpversion() . " cURL)");
|
||||||
$this->http->setHeader("Accept", "image/jpeg,image/png,image/gif");
|
$this->http->setHeader("Accept", "image/jpeg,image/png,image/gif");
|
||||||
|
|
||||||
if ($this->useCache) {
|
if ($this->useCache) {
|
||||||
@@ -514,6 +555,8 @@ class CRemoteImage
|
|||||||
*
|
*
|
||||||
* @param string $url a remote url.
|
* @param string $url a remote url.
|
||||||
*
|
*
|
||||||
|
* @throws Exception when status code does not match 200 or 304.
|
||||||
|
*
|
||||||
* @return string as path to downloaded file or false if failed.
|
* @return string as path to downloaded file or false if failed.
|
||||||
*/
|
*/
|
||||||
public function download($url)
|
public function download($url)
|
||||||
@@ -546,7 +589,7 @@ class CRemoteImage
|
|||||||
return $this->updateCacheDetails();
|
return $this->updateCacheDetails();
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
throw new Exception("Unknown statuscode when downloading remote image: " . $this->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -597,6 +640,285 @@ class CRemoteImage
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Act as whitelist (or blacklist).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class CWhitelist
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Array to contain the whitelist options.
|
||||||
|
*/
|
||||||
|
private $whitelist = array();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the whitelist from an array of strings, each item in the
|
||||||
|
* whitelist should be a regexp without the surrounding / or #.
|
||||||
|
*
|
||||||
|
* @param array $whitelist with all valid options,
|
||||||
|
* default is to clear the whitelist.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function set($whitelist = array())
|
||||||
|
{
|
||||||
|
if (!is_array($whitelist)) {
|
||||||
|
throw new Exception("Whitelist is not of a supported format.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->whitelist = $whitelist;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if item exists in the whitelist.
|
||||||
|
*
|
||||||
|
* @param string $item string to check.
|
||||||
|
* @param array $whitelist optional with all valid options, default is null.
|
||||||
|
*
|
||||||
|
* @return boolean true if item is in whitelist, else false.
|
||||||
|
*/
|
||||||
|
public function check($item, $whitelist = null)
|
||||||
|
{
|
||||||
|
if ($whitelist !== null) {
|
||||||
|
$this->set($whitelist);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($item) or empty($this->whitelist)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->whitelist as $regexp) {
|
||||||
|
if (preg_match("#$regexp#", $item)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an ASCII version of an image.
|
||||||
|
* Inspired by https://gist.github.com/donatj/1353237 and various sources.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class CAsciiArt
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Character set to use.
|
||||||
|
*/
|
||||||
|
private $characterSet = array(
|
||||||
|
'one' => "#0XT|:,.' ",
|
||||||
|
'two' => "@%#*+=-:. ",
|
||||||
|
'three' => "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. "
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current character set.
|
||||||
|
*/
|
||||||
|
private $characters = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Length of current character set.
|
||||||
|
*/
|
||||||
|
private $charCount = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scale of the area to swap to a character.
|
||||||
|
*/
|
||||||
|
private $scale = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strategy to calculate luminance.
|
||||||
|
*/
|
||||||
|
private $luminanceStrategy = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor which sets default options.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->setOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a custom character set.
|
||||||
|
*
|
||||||
|
* @param string $key for the character set.
|
||||||
|
* @param string $value for the character set.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function addCharacterSet($key, $value)
|
||||||
|
{
|
||||||
|
$this->characterSet[$key] = $value;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Length of current character set.
|
||||||
|
*
|
||||||
|
* @param array $options to use as default settings.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setOptions($options = array())
|
||||||
|
{
|
||||||
|
$default = array(
|
||||||
|
"characterSet" => 'two',
|
||||||
|
"scale" => 14,
|
||||||
|
"luminanceStrategy" => 3,
|
||||||
|
"customCharacterSet" => null,
|
||||||
|
);
|
||||||
|
$default = array_merge($default, $options);
|
||||||
|
|
||||||
|
if (!is_null($default['customCharacterSet'])) {
|
||||||
|
$this->addCharacterSet('custom', $default['customCharacterSet']);
|
||||||
|
$default['characterSet'] = 'custom';
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->scale = $default['scale'];
|
||||||
|
$this->characters = $this->characterSet[$default['characterSet']];
|
||||||
|
$this->charCount = strlen($this->characters);
|
||||||
|
$this->luminanceStrategy = $default['luminanceStrategy'];
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an Ascii image from an image file.
|
||||||
|
*
|
||||||
|
* @param string $filename of the image to use.
|
||||||
|
*
|
||||||
|
* @return string $ascii with the ASCII image.
|
||||||
|
*/
|
||||||
|
public function createFromFile($filename)
|
||||||
|
{
|
||||||
|
$img = imagecreatefromstring(file_get_contents($filename));
|
||||||
|
list($width, $height) = getimagesize($filename);
|
||||||
|
|
||||||
|
$ascii = null;
|
||||||
|
$incY = $this->scale;
|
||||||
|
$incX = $this->scale / 2;
|
||||||
|
|
||||||
|
for ($y = 0; $y < $height - 1; $y += $incY) {
|
||||||
|
for ($x = 0; $x < $width - 1; $x += $incX) {
|
||||||
|
$toX = min($x + $this->scale / 2, $width - 1);
|
||||||
|
$toY = min($y + $this->scale, $height - 1);
|
||||||
|
$luminance = $this->luminanceAreaAverage($img, $x, $y, $toX, $toY);
|
||||||
|
$ascii .= $this->luminance2character($luminance);
|
||||||
|
}
|
||||||
|
$ascii .= PHP_EOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ascii;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the luminance from a region of an image using average color value.
|
||||||
|
*
|
||||||
|
* @param string $img the image.
|
||||||
|
* @param integer $x1 the area to get pixels from.
|
||||||
|
* @param integer $y1 the area to get pixels from.
|
||||||
|
* @param integer $x2 the area to get pixels from.
|
||||||
|
* @param integer $y2 the area to get pixels from.
|
||||||
|
*
|
||||||
|
* @return integer $luminance with a value between 0 and 100.
|
||||||
|
*/
|
||||||
|
public function luminanceAreaAverage($img, $x1, $y1, $x2, $y2)
|
||||||
|
{
|
||||||
|
$numPixels = ($x2 - $x1 + 1) * ($y2 - $y1 + 1);
|
||||||
|
$luminance = 0;
|
||||||
|
|
||||||
|
for ($x = $x1; $x <= $x2; $x++) {
|
||||||
|
for ($y = $y1; $y <= $y2; $y++) {
|
||||||
|
$rgb = imagecolorat($img, $x, $y);
|
||||||
|
$red = (($rgb >> 16) & 0xFF);
|
||||||
|
$green = (($rgb >> 8) & 0xFF);
|
||||||
|
$blue = ($rgb & 0xFF);
|
||||||
|
$luminance += $this->getLuminance($red, $green, $blue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $luminance / $numPixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate luminance value with different strategies.
|
||||||
|
*
|
||||||
|
* @param integer $red The color red.
|
||||||
|
* @param integer $green The color green.
|
||||||
|
* @param integer $blue The color blue.
|
||||||
|
*
|
||||||
|
* @return float $luminance with a value between 0 and 1.
|
||||||
|
*/
|
||||||
|
public function getLuminance($red, $green, $blue)
|
||||||
|
{
|
||||||
|
switch($this->luminanceStrategy) {
|
||||||
|
case 1:
|
||||||
|
$luminance = ($red * 0.2126 + $green * 0.7152 + $blue * 0.0722) / 255;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
$luminance = ($red * 0.299 + $green * 0.587 + $blue * 0.114) / 255;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
$luminance = sqrt(0.299 * pow($red, 2) + 0.587 * pow($green, 2) + 0.114 * pow($blue, 2)) / 255;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
default:
|
||||||
|
$luminance = ($red + $green + $blue) / (255 * 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $luminance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translate the luminance value to a character.
|
||||||
|
*
|
||||||
|
* @param string $position a value between 0-100 representing the
|
||||||
|
* luminance.
|
||||||
|
*
|
||||||
|
* @return string with the ascii character.
|
||||||
|
*/
|
||||||
|
public function luminance2character($luminance)
|
||||||
|
{
|
||||||
|
$position = (int) round($luminance * ($this->charCount - 1));
|
||||||
|
$char = $this->characters[$position];
|
||||||
|
return $char;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resize and crop images on the fly, store generated images in a cache.
|
* Resize and crop images on the fly, store generated images in a cache.
|
||||||
*
|
*
|
||||||
@@ -932,6 +1254,13 @@ class CImage
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* output to ascii can take som options as an array.
|
||||||
|
*/
|
||||||
|
private $asciiOptions = array();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Properties, the class is mutable and the method setOptions()
|
* Properties, the class is mutable and the method setOptions()
|
||||||
* decides (partly) what properties are created.
|
* decides (partly) what properties are created.
|
||||||
@@ -2848,6 +3177,10 @@ class CImage
|
|||||||
header('Content-type: application/json');
|
header('Content-type: application/json');
|
||||||
echo $this->json($file);
|
echo $this->json($file);
|
||||||
exit;
|
exit;
|
||||||
|
} elseif ($format == 'ascii') {
|
||||||
|
header('Content-type: text/plain');
|
||||||
|
echo $this->ascii($file);
|
||||||
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->log("Outputting image: $file");
|
$this->log("Outputting image: $file");
|
||||||
@@ -2939,6 +3272,38 @@ class CImage
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set options for creating ascii version of image.
|
||||||
|
*
|
||||||
|
* @param array $options empty to use default or set options to change.
|
||||||
|
*
|
||||||
|
* @return void.
|
||||||
|
*/
|
||||||
|
public function setAsciiOptions($options = array())
|
||||||
|
{
|
||||||
|
$this->asciiOptions = $options;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an ASCII version from the image details.
|
||||||
|
*
|
||||||
|
* @param string $file the file to output.
|
||||||
|
*
|
||||||
|
* @return string ASCII representation of the image.
|
||||||
|
*/
|
||||||
|
public function ascii($file = null)
|
||||||
|
{
|
||||||
|
$file = $file ? $file : $this->cacheFileName;
|
||||||
|
|
||||||
|
$asciiArt = new CAsciiArt();
|
||||||
|
$asciiArt->setOptions($this->asciiOptions);
|
||||||
|
return $asciiArt->createFromFile($file);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log an event if verbose mode.
|
* Log an event if verbose mode.
|
||||||
*
|
*
|
||||||
@@ -3028,70 +3393,6 @@ EOD;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Act as whitelist (or blacklist).
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class CWhitelist
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Array to contain the whitelist options.
|
|
||||||
*/
|
|
||||||
private $whitelist = array();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the whitelist from an array of strings, each item in the
|
|
||||||
* whitelist should be a regexp without the surrounding / or #.
|
|
||||||
*
|
|
||||||
* @param array $whitelist with all valid options,
|
|
||||||
* default is to clear the whitelist.
|
|
||||||
*
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function set($whitelist = array())
|
|
||||||
{
|
|
||||||
if (!is_array($whitelist)) {
|
|
||||||
throw new Exception("Whitelist is not of a supported format.");
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->whitelist = $whitelist;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if item exists in the whitelist.
|
|
||||||
*
|
|
||||||
* @param string $item string to check.
|
|
||||||
* @param array $whitelist optional with all valid options, default is null.
|
|
||||||
*
|
|
||||||
* @return boolean true if item is in whitelist, else false.
|
|
||||||
*/
|
|
||||||
public function check($item, $whitelist = null)
|
|
||||||
{
|
|
||||||
if ($whitelist !== null) {
|
|
||||||
$this->set($whitelist);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty($item) or empty($this->whitelist)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($this->whitelist as $regexp) {
|
|
||||||
if (preg_match("#$regexp#", $item)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resize and crop images on the fly, store generated images in a cache.
|
* Resize and crop images on the fly, store generated images in a cache.
|
||||||
*
|
*
|
||||||
@@ -3101,12 +3402,12 @@ class CWhitelist
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$version = "v0.7.1 (2015-07-25)";
|
$version = "v0.7.3 (2015-09-01)";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default configuration options, can be overridden in own config-file.
|
* Display error message.
|
||||||
*
|
*
|
||||||
* @param string $msg to display.
|
* @param string $msg to display.
|
||||||
*
|
*
|
||||||
@@ -3847,11 +4148,51 @@ verbose("filters = " . print_r($filters, 1));
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* json - output the image as a JSON object with details on the image.
|
* json - output the image as a JSON object with details on the image.
|
||||||
|
* ascii - output the image as ASCII art.
|
||||||
*/
|
*/
|
||||||
$outputFormat = getDefined('json', 'json', null);
|
$outputFormat = getDefined('json', 'json', null);
|
||||||
|
$outputFormat = getDefined('ascii', 'ascii', $outputFormat);
|
||||||
|
|
||||||
|
verbose("outputformat = $outputFormat");
|
||||||
|
|
||||||
|
if ($outputFormat == 'ascii') {
|
||||||
|
$defaultOptions = getConfig(
|
||||||
|
'ascii-options',
|
||||||
|
array(
|
||||||
|
"characterSet" => 'two',
|
||||||
|
"scale" => 14,
|
||||||
|
"luminanceStrategy" => 3,
|
||||||
|
"customCharacterSet" => null,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$options = get('ascii');
|
||||||
|
$options = explode(',', $options);
|
||||||
|
|
||||||
|
if (isset($options[0]) && !empty($options[0])) {
|
||||||
|
$defaultOptions['characterSet'] = $options[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($options[1]) && !empty($options[1])) {
|
||||||
|
$defaultOptions['scale'] = $options[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($options[2]) && !empty($options[2])) {
|
||||||
|
$defaultOptions['luminanceStrategy'] = $options[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($options) > 3) {
|
||||||
|
// Last option is custom character string
|
||||||
|
unset($options[0]);
|
||||||
|
unset($options[1]);
|
||||||
|
unset($options[2]);
|
||||||
|
$characterString = implode($options);
|
||||||
|
$defaultOptions['customCharacterSet'] = $characterString;
|
||||||
|
}
|
||||||
|
|
||||||
|
$img->setAsciiOptions($defaultOptions);
|
||||||
|
}
|
||||||
|
|
||||||
verbose("json = $outputFormat");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
483
webroot/imgs.php
483
webroot/imgs.php
@@ -58,6 +58,33 @@ class CHttpGet
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build an encoded url.
|
||||||
|
*
|
||||||
|
* @param string $baseUrl This is the original url which will be merged.
|
||||||
|
* @param string $merge Thse parts should be merged into the baseUrl,
|
||||||
|
* the format is as parse_url.
|
||||||
|
*
|
||||||
|
* @return string $url as the modified url.
|
||||||
|
*/
|
||||||
|
public function buildUrl($baseUrl, $merge)
|
||||||
|
{
|
||||||
|
$parts = parse_url($baseUrl);
|
||||||
|
$parts = array_merge($parts, $merge);
|
||||||
|
|
||||||
|
$url = $parts['scheme'];
|
||||||
|
$url .= "://";
|
||||||
|
$url .= $parts['host'];
|
||||||
|
$url .= isset($parts['port'])
|
||||||
|
? ":" . $parts['port']
|
||||||
|
: "" ;
|
||||||
|
$url .= $parts['path'];
|
||||||
|
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the url for the request.
|
* Set the url for the request.
|
||||||
*
|
*
|
||||||
@@ -67,6 +94,18 @@ class CHttpGet
|
|||||||
*/
|
*/
|
||||||
public function setUrl($url)
|
public function setUrl($url)
|
||||||
{
|
{
|
||||||
|
$parts = parse_url($url);
|
||||||
|
|
||||||
|
$path = "";
|
||||||
|
if (isset($parts['path'])) {
|
||||||
|
$pathParts = explode('/', $parts['path']);
|
||||||
|
unset($pathParts[0]);
|
||||||
|
foreach ($pathParts as $value) {
|
||||||
|
$path .= "/" . rawurlencode($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$url = $this->buildUrl($url, array("path" => $path));
|
||||||
|
|
||||||
$this->request['url'] = $url;
|
$this->request['url'] = $url;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@@ -130,6 +169,8 @@ class CHttpGet
|
|||||||
*
|
*
|
||||||
* @param boolean $debug set to true to dump headers.
|
* @param boolean $debug set to true to dump headers.
|
||||||
*
|
*
|
||||||
|
* @throws Exception when curl fails to retrieve url.
|
||||||
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function doGet($debug = false)
|
public function doGet($debug = false)
|
||||||
@@ -152,7 +193,7 @@ class CHttpGet
|
|||||||
$response = curl_exec($ch);
|
$response = curl_exec($ch);
|
||||||
|
|
||||||
if (!$response) {
|
if (!$response) {
|
||||||
return false;
|
throw new Exception("Failed retrieving url, details follows: " . curl_error($ch));
|
||||||
}
|
}
|
||||||
|
|
||||||
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
|
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
|
||||||
@@ -435,7 +476,7 @@ class CRemoteImage
|
|||||||
*/
|
*/
|
||||||
public function setHeaderFields()
|
public function setHeaderFields()
|
||||||
{
|
{
|
||||||
$this->http->setHeader("User-Agent", "CImage/0.7.0 (PHP/". phpversion() . " cURL)");
|
$this->http->setHeader("User-Agent", "CImage/0.7.2 (PHP/". phpversion() . " cURL)");
|
||||||
$this->http->setHeader("Accept", "image/jpeg,image/png,image/gif");
|
$this->http->setHeader("Accept", "image/jpeg,image/png,image/gif");
|
||||||
|
|
||||||
if ($this->useCache) {
|
if ($this->useCache) {
|
||||||
@@ -514,6 +555,8 @@ class CRemoteImage
|
|||||||
*
|
*
|
||||||
* @param string $url a remote url.
|
* @param string $url a remote url.
|
||||||
*
|
*
|
||||||
|
* @throws Exception when status code does not match 200 or 304.
|
||||||
|
*
|
||||||
* @return string as path to downloaded file or false if failed.
|
* @return string as path to downloaded file or false if failed.
|
||||||
*/
|
*/
|
||||||
public function download($url)
|
public function download($url)
|
||||||
@@ -546,7 +589,7 @@ class CRemoteImage
|
|||||||
return $this->updateCacheDetails();
|
return $this->updateCacheDetails();
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
throw new Exception("Unknown statuscode when downloading remote image: " . $this->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -597,6 +640,285 @@ class CRemoteImage
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Act as whitelist (or blacklist).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class CWhitelist
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Array to contain the whitelist options.
|
||||||
|
*/
|
||||||
|
private $whitelist = array();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the whitelist from an array of strings, each item in the
|
||||||
|
* whitelist should be a regexp without the surrounding / or #.
|
||||||
|
*
|
||||||
|
* @param array $whitelist with all valid options,
|
||||||
|
* default is to clear the whitelist.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function set($whitelist = array())
|
||||||
|
{
|
||||||
|
if (!is_array($whitelist)) {
|
||||||
|
throw new Exception("Whitelist is not of a supported format.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->whitelist = $whitelist;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if item exists in the whitelist.
|
||||||
|
*
|
||||||
|
* @param string $item string to check.
|
||||||
|
* @param array $whitelist optional with all valid options, default is null.
|
||||||
|
*
|
||||||
|
* @return boolean true if item is in whitelist, else false.
|
||||||
|
*/
|
||||||
|
public function check($item, $whitelist = null)
|
||||||
|
{
|
||||||
|
if ($whitelist !== null) {
|
||||||
|
$this->set($whitelist);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($item) or empty($this->whitelist)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->whitelist as $regexp) {
|
||||||
|
if (preg_match("#$regexp#", $item)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an ASCII version of an image.
|
||||||
|
* Inspired by https://gist.github.com/donatj/1353237 and various sources.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class CAsciiArt
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Character set to use.
|
||||||
|
*/
|
||||||
|
private $characterSet = array(
|
||||||
|
'one' => "#0XT|:,.' ",
|
||||||
|
'two' => "@%#*+=-:. ",
|
||||||
|
'three' => "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. "
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current character set.
|
||||||
|
*/
|
||||||
|
private $characters = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Length of current character set.
|
||||||
|
*/
|
||||||
|
private $charCount = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scale of the area to swap to a character.
|
||||||
|
*/
|
||||||
|
private $scale = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strategy to calculate luminance.
|
||||||
|
*/
|
||||||
|
private $luminanceStrategy = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor which sets default options.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->setOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a custom character set.
|
||||||
|
*
|
||||||
|
* @param string $key for the character set.
|
||||||
|
* @param string $value for the character set.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function addCharacterSet($key, $value)
|
||||||
|
{
|
||||||
|
$this->characterSet[$key] = $value;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Length of current character set.
|
||||||
|
*
|
||||||
|
* @param array $options to use as default settings.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setOptions($options = array())
|
||||||
|
{
|
||||||
|
$default = array(
|
||||||
|
"characterSet" => 'two',
|
||||||
|
"scale" => 14,
|
||||||
|
"luminanceStrategy" => 3,
|
||||||
|
"customCharacterSet" => null,
|
||||||
|
);
|
||||||
|
$default = array_merge($default, $options);
|
||||||
|
|
||||||
|
if (!is_null($default['customCharacterSet'])) {
|
||||||
|
$this->addCharacterSet('custom', $default['customCharacterSet']);
|
||||||
|
$default['characterSet'] = 'custom';
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->scale = $default['scale'];
|
||||||
|
$this->characters = $this->characterSet[$default['characterSet']];
|
||||||
|
$this->charCount = strlen($this->characters);
|
||||||
|
$this->luminanceStrategy = $default['luminanceStrategy'];
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an Ascii image from an image file.
|
||||||
|
*
|
||||||
|
* @param string $filename of the image to use.
|
||||||
|
*
|
||||||
|
* @return string $ascii with the ASCII image.
|
||||||
|
*/
|
||||||
|
public function createFromFile($filename)
|
||||||
|
{
|
||||||
|
$img = imagecreatefromstring(file_get_contents($filename));
|
||||||
|
list($width, $height) = getimagesize($filename);
|
||||||
|
|
||||||
|
$ascii = null;
|
||||||
|
$incY = $this->scale;
|
||||||
|
$incX = $this->scale / 2;
|
||||||
|
|
||||||
|
for ($y = 0; $y < $height - 1; $y += $incY) {
|
||||||
|
for ($x = 0; $x < $width - 1; $x += $incX) {
|
||||||
|
$toX = min($x + $this->scale / 2, $width - 1);
|
||||||
|
$toY = min($y + $this->scale, $height - 1);
|
||||||
|
$luminance = $this->luminanceAreaAverage($img, $x, $y, $toX, $toY);
|
||||||
|
$ascii .= $this->luminance2character($luminance);
|
||||||
|
}
|
||||||
|
$ascii .= PHP_EOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ascii;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the luminance from a region of an image using average color value.
|
||||||
|
*
|
||||||
|
* @param string $img the image.
|
||||||
|
* @param integer $x1 the area to get pixels from.
|
||||||
|
* @param integer $y1 the area to get pixels from.
|
||||||
|
* @param integer $x2 the area to get pixels from.
|
||||||
|
* @param integer $y2 the area to get pixels from.
|
||||||
|
*
|
||||||
|
* @return integer $luminance with a value between 0 and 100.
|
||||||
|
*/
|
||||||
|
public function luminanceAreaAverage($img, $x1, $y1, $x2, $y2)
|
||||||
|
{
|
||||||
|
$numPixels = ($x2 - $x1 + 1) * ($y2 - $y1 + 1);
|
||||||
|
$luminance = 0;
|
||||||
|
|
||||||
|
for ($x = $x1; $x <= $x2; $x++) {
|
||||||
|
for ($y = $y1; $y <= $y2; $y++) {
|
||||||
|
$rgb = imagecolorat($img, $x, $y);
|
||||||
|
$red = (($rgb >> 16) & 0xFF);
|
||||||
|
$green = (($rgb >> 8) & 0xFF);
|
||||||
|
$blue = ($rgb & 0xFF);
|
||||||
|
$luminance += $this->getLuminance($red, $green, $blue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $luminance / $numPixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate luminance value with different strategies.
|
||||||
|
*
|
||||||
|
* @param integer $red The color red.
|
||||||
|
* @param integer $green The color green.
|
||||||
|
* @param integer $blue The color blue.
|
||||||
|
*
|
||||||
|
* @return float $luminance with a value between 0 and 1.
|
||||||
|
*/
|
||||||
|
public function getLuminance($red, $green, $blue)
|
||||||
|
{
|
||||||
|
switch($this->luminanceStrategy) {
|
||||||
|
case 1:
|
||||||
|
$luminance = ($red * 0.2126 + $green * 0.7152 + $blue * 0.0722) / 255;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
$luminance = ($red * 0.299 + $green * 0.587 + $blue * 0.114) / 255;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
$luminance = sqrt(0.299 * pow($red, 2) + 0.587 * pow($green, 2) + 0.114 * pow($blue, 2)) / 255;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
default:
|
||||||
|
$luminance = ($red + $green + $blue) / (255 * 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $luminance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translate the luminance value to a character.
|
||||||
|
*
|
||||||
|
* @param string $position a value between 0-100 representing the
|
||||||
|
* luminance.
|
||||||
|
*
|
||||||
|
* @return string with the ascii character.
|
||||||
|
*/
|
||||||
|
public function luminance2character($luminance)
|
||||||
|
{
|
||||||
|
$position = (int) round($luminance * ($this->charCount - 1));
|
||||||
|
$char = $this->characters[$position];
|
||||||
|
return $char;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resize and crop images on the fly, store generated images in a cache.
|
* Resize and crop images on the fly, store generated images in a cache.
|
||||||
*
|
*
|
||||||
@@ -932,6 +1254,13 @@ class CImage
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* output to ascii can take som options as an array.
|
||||||
|
*/
|
||||||
|
private $asciiOptions = array();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Properties, the class is mutable and the method setOptions()
|
* Properties, the class is mutable and the method setOptions()
|
||||||
* decides (partly) what properties are created.
|
* decides (partly) what properties are created.
|
||||||
@@ -2848,6 +3177,10 @@ class CImage
|
|||||||
header('Content-type: application/json');
|
header('Content-type: application/json');
|
||||||
echo $this->json($file);
|
echo $this->json($file);
|
||||||
exit;
|
exit;
|
||||||
|
} elseif ($format == 'ascii') {
|
||||||
|
header('Content-type: text/plain');
|
||||||
|
echo $this->ascii($file);
|
||||||
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->log("Outputting image: $file");
|
$this->log("Outputting image: $file");
|
||||||
@@ -2939,6 +3272,38 @@ class CImage
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set options for creating ascii version of image.
|
||||||
|
*
|
||||||
|
* @param array $options empty to use default or set options to change.
|
||||||
|
*
|
||||||
|
* @return void.
|
||||||
|
*/
|
||||||
|
public function setAsciiOptions($options = array())
|
||||||
|
{
|
||||||
|
$this->asciiOptions = $options;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an ASCII version from the image details.
|
||||||
|
*
|
||||||
|
* @param string $file the file to output.
|
||||||
|
*
|
||||||
|
* @return string ASCII representation of the image.
|
||||||
|
*/
|
||||||
|
public function ascii($file = null)
|
||||||
|
{
|
||||||
|
$file = $file ? $file : $this->cacheFileName;
|
||||||
|
|
||||||
|
$asciiArt = new CAsciiArt();
|
||||||
|
$asciiArt->setOptions($this->asciiOptions);
|
||||||
|
return $asciiArt->createFromFile($file);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log an event if verbose mode.
|
* Log an event if verbose mode.
|
||||||
*
|
*
|
||||||
@@ -3028,70 +3393,6 @@ EOD;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Act as whitelist (or blacklist).
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class CWhitelist
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Array to contain the whitelist options.
|
|
||||||
*/
|
|
||||||
private $whitelist = array();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the whitelist from an array of strings, each item in the
|
|
||||||
* whitelist should be a regexp without the surrounding / or #.
|
|
||||||
*
|
|
||||||
* @param array $whitelist with all valid options,
|
|
||||||
* default is to clear the whitelist.
|
|
||||||
*
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function set($whitelist = array())
|
|
||||||
{
|
|
||||||
if (!is_array($whitelist)) {
|
|
||||||
throw new Exception("Whitelist is not of a supported format.");
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->whitelist = $whitelist;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if item exists in the whitelist.
|
|
||||||
*
|
|
||||||
* @param string $item string to check.
|
|
||||||
* @param array $whitelist optional with all valid options, default is null.
|
|
||||||
*
|
|
||||||
* @return boolean true if item is in whitelist, else false.
|
|
||||||
*/
|
|
||||||
public function check($item, $whitelist = null)
|
|
||||||
{
|
|
||||||
if ($whitelist !== null) {
|
|
||||||
$this->set($whitelist);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty($item) or empty($this->whitelist)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($this->whitelist as $regexp) {
|
|
||||||
if (preg_match("#$regexp#", $item)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resize and crop images on the fly, store generated images in a cache.
|
* Resize and crop images on the fly, store generated images in a cache.
|
||||||
*
|
*
|
||||||
@@ -3101,12 +3402,12 @@ class CWhitelist
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$version = "v0.7.1 (2015-07-25)";
|
$version = "v0.7.3 (2015-09-01)";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default configuration options, can be overridden in own config-file.
|
* Display error message.
|
||||||
*
|
*
|
||||||
* @param string $msg to display.
|
* @param string $msg to display.
|
||||||
*
|
*
|
||||||
@@ -3847,11 +4148,51 @@ verbose("filters = " . print_r($filters, 1));
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* json - output the image as a JSON object with details on the image.
|
* json - output the image as a JSON object with details on the image.
|
||||||
|
* ascii - output the image as ASCII art.
|
||||||
*/
|
*/
|
||||||
$outputFormat = getDefined('json', 'json', null);
|
$outputFormat = getDefined('json', 'json', null);
|
||||||
|
$outputFormat = getDefined('ascii', 'ascii', $outputFormat);
|
||||||
|
|
||||||
|
verbose("outputformat = $outputFormat");
|
||||||
|
|
||||||
|
if ($outputFormat == 'ascii') {
|
||||||
|
$defaultOptions = getConfig(
|
||||||
|
'ascii-options',
|
||||||
|
array(
|
||||||
|
"characterSet" => 'two',
|
||||||
|
"scale" => 14,
|
||||||
|
"luminanceStrategy" => 3,
|
||||||
|
"customCharacterSet" => null,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$options = get('ascii');
|
||||||
|
$options = explode(',', $options);
|
||||||
|
|
||||||
|
if (isset($options[0]) && !empty($options[0])) {
|
||||||
|
$defaultOptions['characterSet'] = $options[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($options[1]) && !empty($options[1])) {
|
||||||
|
$defaultOptions['scale'] = $options[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($options[2]) && !empty($options[2])) {
|
||||||
|
$defaultOptions['luminanceStrategy'] = $options[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($options) > 3) {
|
||||||
|
// Last option is custom character string
|
||||||
|
unset($options[0]);
|
||||||
|
unset($options[1]);
|
||||||
|
unset($options[2]);
|
||||||
|
$characterString = implode($options);
|
||||||
|
$defaultOptions['customCharacterSet'] = $characterString;
|
||||||
|
}
|
||||||
|
|
||||||
|
$img->setAsciiOptions($defaultOptions);
|
||||||
|
}
|
||||||
|
|
||||||
verbose("json = $outputFormat");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user