Compare commits
157 Commits
v0.1.1
...
v0.7.0-rc.
Author | SHA1 | Date | |
---|---|---|---|
|
c2b037af0d | ||
|
889dba1ddb | ||
|
0baea7c346 | ||
|
ab4e8a6fae | ||
|
641d67d7a0 | ||
|
aa009510be | ||
|
9348141e65 | ||
|
800dcbc248 | ||
|
7b18030580 | ||
|
e5738c02b1 | ||
|
6478915f3c | ||
|
ba58ce80c0 | ||
|
d4d645a00e | ||
|
011148b0e8 | ||
|
eb0fc69036 | ||
|
c012cb2537 | ||
|
16a7a3dad5 | ||
|
bc4e04c3cb | ||
|
3452ea1908 | ||
|
5e08e5ed80 | ||
|
4fae208c4c | ||
|
f87dc2967f | ||
|
c35587c7e2 | ||
|
81e70b7acd | ||
|
8e9a3b68f0 | ||
|
61afe445f1 | ||
|
be98ae8979 | ||
|
f9704a4fbc | ||
|
254ddf11f0 | ||
|
d21daa298c | ||
|
cae7a49d21 | ||
|
f4b3f16443 | ||
|
b5100845e9 | ||
|
8c4b22ca66 | ||
|
d509067759 | ||
|
5fa05e8282 | ||
|
1144c8e105 | ||
|
90bfced741 | ||
|
61e0473f47 | ||
|
2dbe33bd8e | ||
|
ece0be086c | ||
|
e236757e5d | ||
|
951231f360 | ||
|
34124e687f | ||
|
ea06d5cfe6 | ||
|
cfc4a5f0ed | ||
|
00dca21be0 | ||
|
9680cd421b | ||
|
b335587aa4 | ||
|
afa59313e6 | ||
|
5dddad60eb | ||
|
af1aa661b9 | ||
|
9015e7ce9d | ||
|
7911a88d6e | ||
|
2b6952b0ca | ||
|
640e377ea9 | ||
|
cdbc9b4adb | ||
|
3aa5542664 | ||
|
3d352f72fe | ||
|
f13b602e11 | ||
|
f638dd16a7 | ||
|
113b62edc0 | ||
|
3c04a2dd0f | ||
|
832edc9d26 | ||
|
2d09ea4b44 | ||
|
9177d72bea | ||
|
d4a03b70dd | ||
|
188f8cd64d | ||
|
4dfbcd9784 | ||
|
35dd5c9064 | ||
|
1f5f8c02a4 | ||
|
08ee3064d0 | ||
|
ba45f746bb | ||
|
ccc59fbb3a | ||
|
e85bc6cee5 | ||
|
3b7485b3b9 | ||
|
c83eac8c3c | ||
|
78ac29752e | ||
|
4b64237a4c | ||
|
85f0e3e7d3 | ||
|
da227d49dd | ||
|
26449a3236 | ||
|
20a4f848b7 | ||
|
ec3a6f3491 | ||
|
8523ef5e31 | ||
|
63112f58b1 | ||
|
c96ed10f80 | ||
|
67524bd090 | ||
|
1f9a11747b | ||
|
4ed55d59e3 | ||
|
8dde82993b | ||
|
fb261b1b05 | ||
|
1a6cef6580 | ||
|
2643d4954f | ||
|
ef1d56085a | ||
|
28cda0ea28 | ||
|
ed9949b717 | ||
|
c249a472d6 | ||
|
c8c2e5f95f | ||
|
8db8501eb0 | ||
|
2b0b3859a7 | ||
|
1e70883771 | ||
|
b2002d0087 | ||
|
9aac0cde8e | ||
|
3dec1d0a6d | ||
|
577e5fa5d4 | ||
|
38a6c86317 | ||
|
dcb390a17b | ||
|
9e461787c7 | ||
|
a96cd7a4cc | ||
|
98d971204f | ||
|
9707065b9e | ||
|
5cd953b9b3 | ||
|
b4f51f3438 | ||
|
dedd01bc71 | ||
|
67d0cf27ee | ||
|
161fdfe769 | ||
|
6cff9ac105 | ||
|
ec42c41e4d | ||
|
f12d02b8c1 | ||
|
1673cd7aca | ||
|
0fee846437 | ||
|
c63747a892 | ||
|
2d8cccc795 | ||
|
bb5fd6f115 | ||
|
0ab7cf7e1b | ||
|
20a621bf48 | ||
|
7478b12751 | ||
|
570fe57240 | ||
|
28f3c55d8c | ||
|
230e9189a3 | ||
|
e886c86f72 | ||
|
d7b6f7e25d | ||
|
7849f69801 | ||
|
7117ac2a4c | ||
|
c03ebedc93 | ||
|
c9d41ceca2 | ||
|
218bd9491a | ||
|
d8a65ae409 | ||
|
c59f44f366 | ||
|
688cd5c000 | ||
|
60c76653b3 | ||
|
47e5cb2327 | ||
|
04fd68cb2b | ||
|
664fd6a3be | ||
|
fedbf9e381 | ||
|
28b107e64f | ||
|
ce63730cb6 | ||
|
0482744f89 | ||
|
0998f2819e | ||
|
9e3c7fae82 | ||
|
e4c436f52c | ||
|
5ac715aa48 | ||
|
0593fec8fb | ||
|
81f05147aa | ||
|
12109803cc | ||
|
e4ff269a60 |
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
# Cache files #
|
||||
######################
|
||||
cache/*
|
||||
|
240
CHttpGet.php
Normal file
@@ -0,0 +1,240 @@
|
||||
<?php
|
||||
/**
|
||||
* Get a image from a remote server using HTTP GET and If-Modified-Since.
|
||||
*
|
||||
*/
|
||||
class CHttpGet
|
||||
{
|
||||
private $request = array();
|
||||
private $response = array();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->request['header'] = array();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set the url for the request.
|
||||
*
|
||||
* @param string $url
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setUrl($url)
|
||||
{
|
||||
$this->request['url'] = $url;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set custom header field for the request.
|
||||
*
|
||||
* @param string $field
|
||||
* @param string $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setHeader($field, $value)
|
||||
{
|
||||
$this->request['header'][] = "$field: $value";
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set header fields for the request.
|
||||
*
|
||||
* @param string $field
|
||||
* @param string $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function parseHeader()
|
||||
{
|
||||
$header = explode("\r\n", rtrim($this->response['headerRaw'], "\r\n"));
|
||||
$output = array();
|
||||
|
||||
if ('HTTP' === substr($header[0], 0, 4)) {
|
||||
list($output['version'], $output['status']) = explode(' ', $header[0]);
|
||||
unset($header[0]);
|
||||
}
|
||||
|
||||
foreach ($header as $entry) {
|
||||
$pos = strpos($entry, ':');
|
||||
$output[trim(substr($entry, 0, $pos))] = trim(substr($entry, $pos + 1));
|
||||
}
|
||||
|
||||
$this->response['header'] = $output;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Perform the request.
|
||||
*
|
||||
* @param boolean $debug set to true to dump headers.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function doGet($debug = false)
|
||||
{
|
||||
$options = array(
|
||||
CURLOPT_URL => $this->request['url'],
|
||||
CURLOPT_HEADER => 1,
|
||||
CURLOPT_HTTPHEADER => $this->request['header'],
|
||||
CURLOPT_AUTOREFERER => true,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLINFO_HEADER_OUT => $debug,
|
||||
CURLOPT_CONNECTTIMEOUT => 5,
|
||||
CURLOPT_TIMEOUT => 5,
|
||||
);
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt_array($ch, $options);
|
||||
$response = curl_exec($ch);
|
||||
|
||||
if (!$response) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
|
||||
$this->response['headerRaw'] = substr($response, 0, $headerSize);
|
||||
$this->response['body'] = substr($response, $headerSize);
|
||||
|
||||
$this->parseHeader();
|
||||
|
||||
if ($debug) {
|
||||
$info = curl_getinfo($ch);
|
||||
echo "Request header<br><pre>", var_dump($info['request_header']), "</pre>";
|
||||
echo "Response header (raw)<br><pre>", var_dump($this->response['headerRaw']), "</pre>";
|
||||
echo "Response header (parsed)<br><pre>", var_dump($this->response['header']), "</pre>";
|
||||
}
|
||||
|
||||
curl_close($ch);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get HTTP code of response.
|
||||
*
|
||||
* @return integer as HTTP status code or null if not available.
|
||||
*/
|
||||
public function getStatus()
|
||||
{
|
||||
return isset($this->response['header']['status'])
|
||||
? (int) $this->response['header']['status']
|
||||
: null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get file modification time of response.
|
||||
*
|
||||
* @return int as timestamp.
|
||||
*/
|
||||
public function getLastModified()
|
||||
{
|
||||
return isset($this->response['header']['Last-Modified'])
|
||||
? strtotime($this->response['header']['Last-Modified'])
|
||||
: null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get content type.
|
||||
*
|
||||
* @return string as the content type or null if not existing or invalid.
|
||||
*/
|
||||
public function getContentType()
|
||||
{
|
||||
$type = isset($this->response['header']['Content-Type'])
|
||||
? $this->response['header']['Content-Type']
|
||||
: null;
|
||||
|
||||
return preg_match('#[a-z]+/[a-z]+#', $type)
|
||||
? $type
|
||||
: null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get file modification time of response.
|
||||
*
|
||||
* @param mixed $default as default value (int seconds) if date is
|
||||
* missing in response header.
|
||||
*
|
||||
* @return int as timestamp or $default if Date is missing in
|
||||
* response header.
|
||||
*/
|
||||
public function getDate($default = false)
|
||||
{
|
||||
return isset($this->response['header']['Date'])
|
||||
? strtotime($this->response['header']['Date'])
|
||||
: $default;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get max age of cachable item.
|
||||
*
|
||||
* @param mixed $default as default value if date is missing in response
|
||||
* header.
|
||||
*
|
||||
* @return int as timestamp or false if not available.
|
||||
*/
|
||||
public function getMaxAge($default = false)
|
||||
{
|
||||
$cacheControl = isset($this->response['header']['Cache-Control'])
|
||||
? $this->response['header']['Cache-Control']
|
||||
: null;
|
||||
|
||||
$maxAge = null;
|
||||
if ($cacheControl) {
|
||||
// max-age=2592000
|
||||
$part = explode('=', $cacheControl);
|
||||
$maxAge = ($part[0] == "max-age")
|
||||
? (int) $part[1]
|
||||
: null;
|
||||
}
|
||||
|
||||
if ($maxAge) {
|
||||
return $maxAge;
|
||||
}
|
||||
|
||||
$expire = isset($this->response['header']['Expires'])
|
||||
? strtotime($this->response['header']['Expires'])
|
||||
: null;
|
||||
|
||||
return $expire ? $expire : $default;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get body of response.
|
||||
*
|
||||
* @return string as body.
|
||||
*/
|
||||
public function getBody()
|
||||
{
|
||||
return $this->response['body'];
|
||||
}
|
||||
}
|
2597
CImage.php
351
CRemoteImage.php
Normal file
@@ -0,0 +1,351 @@
|
||||
<?php
|
||||
/**
|
||||
* Get a image from a remote server using HTTP GET and If-Modified-Since.
|
||||
*
|
||||
*/
|
||||
class CRemoteImage
|
||||
{
|
||||
/**
|
||||
* Path to cache files.
|
||||
*/
|
||||
private $saveFolder = null;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Use cache or not.
|
||||
*/
|
||||
private $useCache = true;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* HTTP object to aid in download file.
|
||||
*/
|
||||
private $http;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Status of the HTTP request.
|
||||
*/
|
||||
private $status;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Defalt age for cached items 60*60*24*7.
|
||||
*/
|
||||
private $defaultMaxAge = 604800;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Url of downloaded item.
|
||||
*/
|
||||
private $url;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Base name of cache file for downloaded item.
|
||||
*/
|
||||
private $fileName;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Filename for json-file with details of cached item.
|
||||
*/
|
||||
private $fileJson;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Filename for image-file.
|
||||
*/
|
||||
private $fileImage;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Cache details loaded from file.
|
||||
*/
|
||||
private $cache;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get status of last HTTP request.
|
||||
*
|
||||
* @return int as status
|
||||
*/
|
||||
public function getStatus()
|
||||
{
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get JSON details for cache item.
|
||||
*
|
||||
* @return array with json details on cache.
|
||||
*/
|
||||
public function getDetails()
|
||||
{
|
||||
return $this->cache;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set the path to the cache directory.
|
||||
*
|
||||
* @param boolean $use true to use the cache and false to ignore cache.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setCache($path)
|
||||
{
|
||||
$this->saveFolder = $path;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Check if cache is writable or throw exception.
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws Exception if cahce folder is not writable.
|
||||
*/
|
||||
public function isCacheWritable()
|
||||
{
|
||||
if (!is_writable($this->saveFolder)) {
|
||||
throw new Exception("Cache folder is not writable for downloaded files.");
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Decide if the cache should be used or not before trying to download
|
||||
* a remote file.
|
||||
*
|
||||
* @param boolean $use true to use the cache and false to ignore cache.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function useCache($use = true)
|
||||
{
|
||||
$this->useCache = $use;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Translate a content type to a file extension.
|
||||
*
|
||||
* @param string $type a valid content type.
|
||||
*
|
||||
* @return string as file extension or false if no match.
|
||||
*/
|
||||
function contentTypeToFileExtension($type) {
|
||||
$extension = array(
|
||||
'image/jpeg' => 'jpg',
|
||||
'image/png' => 'png',
|
||||
'image/gif' => 'gif',
|
||||
);
|
||||
|
||||
return isset($extension[$type])
|
||||
? $extension[$type]
|
||||
: false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set header fields.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
function setHeaderFields() {
|
||||
$this->http->setHeader("User-Agent", "CImage/0.6 (PHP/". phpversion() . " cURL)");
|
||||
$this->http->setHeader("Accept", "image/jpeg,image/png,image/gif");
|
||||
|
||||
if ($this->useCache) {
|
||||
$this->http->setHeader("Cache-Control", "max-age=0");
|
||||
} else {
|
||||
$this->http->setHeader("Cache-Control", "no-cache");
|
||||
$this->http->setHeader("Pragma", "no-cache");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Save downloaded resource to cache.
|
||||
*
|
||||
* @return string as path to saved file or false if not saved.
|
||||
*/
|
||||
function save() {
|
||||
|
||||
$this->cache = array();
|
||||
$date = $this->http->getDate(time());
|
||||
$maxAge = $this->http->getMaxAge($this->defaultMaxAge);
|
||||
$lastModified = $this->http->getLastModified();
|
||||
$type = $this->http->getContentType();
|
||||
$extension = $this->contentTypeToFileExtension($type);
|
||||
|
||||
$this->cache['Date'] = gmdate("D, d M Y H:i:s T", $date);
|
||||
$this->cache['Max-Age'] = $maxAge;
|
||||
$this->cache['Content-Type'] = $type;
|
||||
$this->cache['File-Extension'] = $extension;
|
||||
|
||||
if ($lastModified) {
|
||||
$this->cache['Last-Modified'] = gmdate("D, d M Y H:i:s T", $lastModified);
|
||||
}
|
||||
|
||||
if ($extension) {
|
||||
|
||||
$this->fileImage = $this->fileName . "." . $extension;
|
||||
|
||||
// Save only if body is a valid image
|
||||
$body = $this->http->getBody();
|
||||
$img = imagecreatefromstring($body);
|
||||
|
||||
if ($img !== false) {
|
||||
file_put_contents($this->fileImage, $body);
|
||||
file_put_contents($this->fileJson, json_encode($this->cache));
|
||||
return $this->fileImage;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Got a 304 and updates cache with new age.
|
||||
*
|
||||
* @return string as path to cached file.
|
||||
*/
|
||||
function updateCacheDetails() {
|
||||
|
||||
$date = $this->http->getDate(time());
|
||||
$maxAge = $this->http->getMaxAge($this->defaultMaxAge);
|
||||
$lastModified = $this->http->getLastModified();
|
||||
|
||||
$this->cache['Date'] = gmdate("D, d M Y H:i:s T", $date);
|
||||
$this->cache['Max-Age'] = $maxAge;
|
||||
|
||||
if ($lastModified) {
|
||||
$this->cache['Last-Modified'] = gmdate("D, d M Y H:i:s T", $lastModified);
|
||||
}
|
||||
|
||||
file_put_contents($this->fileJson, json_encode($this->cache));
|
||||
return $this->fileImage;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Download a remote file and keep a cache of downloaded files.
|
||||
*
|
||||
* @param string $url a remote url.
|
||||
*
|
||||
* @return string as path to downloaded file or false if failed.
|
||||
*/
|
||||
function download($url) {
|
||||
|
||||
$this->http = new CHttpGet();
|
||||
$this->url = $url;
|
||||
|
||||
// First check if the cache is valid and can be used
|
||||
$this->loadCacheDetails();
|
||||
|
||||
if ($this->useCache) {
|
||||
$src = $this->getCachedSource();
|
||||
if ($src) {
|
||||
$this->status = 1;
|
||||
return $src;
|
||||
}
|
||||
}
|
||||
|
||||
// Do a HTTP request to download item
|
||||
$this->setHeaderFields();
|
||||
$this->http->setUrl($this->url);
|
||||
$this->http->doGet();
|
||||
|
||||
$this->status = $this->http->getStatus();
|
||||
if ($this->status === 200) {
|
||||
$this->isCacheWritable();
|
||||
return $this->save();
|
||||
} else if ($this->status === 304) {
|
||||
$this->isCacheWritable();
|
||||
return $this->updateCacheDetails();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the path to the cached image file if the cache is valid.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function loadCacheDetails()
|
||||
{
|
||||
$cacheFile = str_replace(array("/", ":", "#", ".", "?"), "-", $this->url);
|
||||
$this->fileName = $this->saveFolder . $cacheFile;
|
||||
$this->fileJson = $this->fileName . ".json";
|
||||
if (is_readable($this->fileJson)) {
|
||||
$this->cache = json_decode(file_get_contents($this->fileJson), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the path to the cached image file if the cache is valid.
|
||||
*
|
||||
* @return string as the path ot the image file or false if no cache.
|
||||
*/
|
||||
public function getCachedSource()
|
||||
{
|
||||
$this->fileImage = $this->fileName . "." . $this->cache['File-Extension'];
|
||||
$imageExists = is_readable($this->fileImage);
|
||||
|
||||
// Is cache valid?
|
||||
$date = strtotime($this->cache['Date']);
|
||||
$maxAge = $this->cache['Max-Age'];
|
||||
$now = time();
|
||||
if ($imageExists && $date + $maxAge > $now) {
|
||||
return $this->fileImage;
|
||||
}
|
||||
|
||||
// Prepare for a 304 if available
|
||||
if ($imageExists && isset($this->cache['Last-Modified'])) {
|
||||
$this->http->setHeader("If-Modified-Since", $this->cache['Last-Modified']);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
23
LICENSE.txt
@@ -1,2 +1,21 @@
|
||||
This is a software solution to a general known problem.
|
||||
Free software. Use at own risk.
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2012 - 2014 Mikael Roos, me@mikaelroos.se
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
286
README.md
@@ -1,31 +1,281 @@
|
||||
Image conversion on the fly using PHP
|
||||
=====================================
|
||||
|
||||
The `CImage.php` contains a class that can resize and crop images and output them to
|
||||
a webpage. The class has cache of generated images.
|
||||
About
|
||||
-------------------------------------
|
||||
|
||||
The file `img.php` uses `CImage.php` to resize images. It is a usecase on how to use
|
||||
the class.
|
||||
`CImage` is a PHP class enabling resizing of images through scaling and cropping together with filtering effects -- all using PHP GD. The script `img.php` uses `CImage` to enable server-side image processing together with caching and optimization of the processed images.
|
||||
|
||||
The file `test.php` has some testcases that show the results of `img.php` with different
|
||||
settings.
|
||||
Server-side image processing is a most useful tool for any web developer, `img.php` has an easy to use interface and its powerful when you integrate it with your website. Using it might decrease the time and effort put in managing images and improve your workflow when creating content for websites.
|
||||
|
||||
Start by reviewing the `test.php`, then have a look at `img.php` and finally go through
|
||||
`CImage.php`.
|
||||
|
||||
Enjoy.
|
||||
|
||||
Mikael Roos (mos@dbwebb.se)
|
||||
This software is free and open source, licensed according MIT.
|
||||
|
||||
|
||||
Revision history
|
||||
----------------
|
||||
|
||||
v0.1.1 (2012-04-27)
|
||||
Use case
|
||||
--------------------------------------
|
||||
|
||||
* Corrected calculation where both width and height were set.
|
||||
You got an image from your friend who took it with the iPhone and you want to put it up on your website.
|
||||
|
||||
<img src="http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=issue36/me-270.jpg&w=300" alt="">
|
||||
|
||||
The original image is looking like this one, scaled down to a width of 300 pixels.
|
||||
|
||||
So, you need to rotate it and crop off some parts to make it intresting.
|
||||
|
||||
To show it off, I'll autorotate the image based on its EXIF-information, I will crop it to a thumbnail of 100x100 pixels and add a filter to make it greyscale finishing up with a sharpen effect. Just for the show I'll rotate the image 25 degrees - do not ask me why.
|
||||
|
||||
Lets call this *the URL-Photoshopper*. This is how the magic looks like.
|
||||
|
||||
`img.php?src=issue36/me-270.jpg&w=100&h=100&cf&aro&rb=-25&a=8,30,30,38&f=grayscale`<br>`&convolve=sharpen-alt`
|
||||
|
||||
<img src="http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=issue36/me-270.jpg&w=100&h=100&cf&aro&rb=-25&a=8,30,30,38&f=grayscale&convolve=sharpen-alt" alt="">
|
||||
|
||||
For myself, I use `img.php` to put up all images on my website, it gives me the power of affecting the resulting images - without opening up a photo-editing application.
|
||||
|
||||
|
||||
v0.1 (2012-04-25)
|
||||
|
||||
* Initial release after rewriting some older code I had lying around.
|
||||
Requirements
|
||||
--------------------------------------
|
||||
|
||||
`CImage` and `img.php` supports GIF (with transparency), JPEG and PNG (8bit transparent, 24bit semi transparent) images. It requires PHP 5.3 and PHP GD. You optionally need the EXIF extension to support auto-rotation of JPEG-images.
|
||||
|
||||
|
||||
|
||||
Installation
|
||||
--------------------------------------
|
||||
|
||||
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).
|
||||
|
||||
I prefer cloning like this. Do switch to the latest stable version.
|
||||
|
||||
**Latest stable version is v0.6.1 released 2015-01-08.**
|
||||
|
||||
```bash
|
||||
git clone git://github.com/mosbth/cimage.git
|
||||
cd cimage
|
||||
git checkout v0.6.1
|
||||
```
|
||||
|
||||
Make the cache-directory writable by the webserver.
|
||||
|
||||
```bash
|
||||
chmod 777 cache
|
||||
```
|
||||
|
||||
|
||||
|
||||
Get going quickly
|
||||
--------------------------------------
|
||||
|
||||
|
||||
|
||||
###Check out the test page
|
||||
|
||||
Try it out by pointing your browser to the test file `webroot/test/test.php`. It will show some images and you can review how they are created.
|
||||
|
||||
|
||||
|
||||
###Process your first image
|
||||
|
||||
<img src="http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim04.png&w=w2&a=40,0,50,0" alt=''>
|
||||
|
||||
Try it yourself by opening up an image in your browser. Start with `webroot/img.php?src=kodim04.png` and then try to resize it to a thumbnail `webroot/img.php?src=kodim04.png&width=100&height=100&crop-to-fit`.
|
||||
|
||||
|
||||
|
||||
###What does "processing the image" involves?
|
||||
|
||||
Add `&verbose` to the link to get a verbose output of what is happens during image processing. This is useful for developers or those who seek a deeper understanding on how it all works.
|
||||
|
||||
|
||||
|
||||
###Check your system
|
||||
|
||||
Open up `webroot/check_system.php` if you need to troubleshoot or if you are uncertain if your system has the right extensions loaded.
|
||||
|
||||
|
||||
|
||||
###How does it work?
|
||||
|
||||
Review the settings in `webroot/img_config.php` and check out `webroot/img.php` on how it uses `CImage`.
|
||||
|
||||
The programatic flow, just to get you oriented in the environment, is.
|
||||
|
||||
1. Start in `img.php`.
|
||||
2. `img.php` reads configuration details from `img_config.php`.
|
||||
3. `img.php` reads and processes incoming `$_GET` arguments to prepare using `CImage`.
|
||||
4. `img.php` uses `CImage`.
|
||||
5. `CImage` processes and outputs the image according to how its used.
|
||||
|
||||
Read on to learn more on how to use `img.php`.
|
||||
|
||||
|
||||
|
||||
Basic usage
|
||||
--------------------------------------
|
||||
|
||||
|
||||
|
||||
###Select the source
|
||||
|
||||
Open an image through `img.php` by using its `src` attribute.
|
||||
|
||||
> `img.php?src=kodim13.png`
|
||||
|
||||
It looks like this.
|
||||
|
||||
<img src=http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim13.png&w=w1&save-as=jpg alt="">
|
||||
|
||||
All images are stored in a directory structure and you access them as `?src=dir1/dir2/image.png`.
|
||||
|
||||
|
||||
|
||||
###Resize using constraints on width and height
|
||||
|
||||
Create a thumbnail of the image by applying constraints on width and height, or one of them.
|
||||
|
||||
| `&width=150` | `&height=150` | `&w=150&h=150` |
|
||||
|---------------------|---------------------|---------------------|
|
||||
| <img src=http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim13.png&w=150 alt=''> | <img src=http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim13.png&h=150 alt=''> | <img src=http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim13.png&w=150&h=150 alt=''> |
|
||||
|
||||
By setting width, height or both, the image gets resized to be *not larger* than the defined dimensions *and* keeping its original aspect ratio.
|
||||
|
||||
Think of the constraints as a imaginary box where the image should fit. With `width=150` and `height=150` the box would have the dimension of 150x150px. A landscape image would fit in that box and its width would be 150px and its height depending on the aspect ratio, but for sure less than 150px. A portrait image would fit with a height of 150px and the width depending on the aspect ratio, but surely less than 150px.
|
||||
|
||||
|
||||
|
||||
###Resize to fit a certain dimension
|
||||
|
||||
Creating a thumbnail with a certain dimension of width and height, usually involves stretching or cropping the image to fit in the selected dimensions. Here is how you create a image that has the exact dimensions of 300x150 pixels, by either *stretching*, *cropping* or *fill to fit*.
|
||||
|
||||
|
||||
| What | The image |
|
||||
|---------------------|---------------------|
|
||||
| **Original.** The original image resized with a max width and max height.<br>`?w=300&h=150` | <img src=http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim13.png&w=300&h=150 alt=''> |
|
||||
| **Stretch.** Stretch the image so that the resulting image has the defined width and height.<br>`?w=300&h=150&stretch` | <img src=http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim13.png&w=300&h=150&stretch alt=''> |
|
||||
| **Crop to fit.** Keep the aspect ratio and crop out the parts of the image that does not fit.<br>`?w=300&h=150&crop-to-fit` | <img src=http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim13.png&w=300&h=150&crop-to-fit alt=''> |
|
||||
| **Fill to fit.** Keep the aspect ratio and fill then blank space with a background color.<br>`?w=300&h=150&fill-to-fit=006600` | <img src=http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim13.png&w=300&h=150&fill-to-fit=006600 alt=''> |
|
||||
|
||||
Learn to crop your images, creative cropping can make wonderful images from appearingly useless originals.
|
||||
|
||||
Stretching might work, like in the above example where you can not really notice that the image is stretched. But usually, stretching is not that a good option since it distorts the ratio resulting in a image with incorrect dimensions. Stretching a face may not turn out particularly well.
|
||||
|
||||
Fill to fit is useful when you have some image that must fit in a certain dimension and stretching nor cropping can do it. Carefully choose the background color to make a good resulting image. Choose the same background color as your website and no one will notice.
|
||||
|
||||
|
||||
|
||||
###List of parameters
|
||||
|
||||
`img.php` supports a lot of parameters. Combine the parameters to get the desired behavior and resulting image. For example, take the original image, resize it using width, aspect-ratio and crop-to-fit, apply a sharpen effect, save the image as JPEG using quality 30.
|
||||
|
||||
| `img.php?src=kodim13.png&w=600&aspect-ratio=4&crop-to-fit&sharpen&save-as=jpg&q=30` |
|
||||
|-----------------------------------------------------------|
|
||||
| <img src=http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim13.png&w=600&aspect-ratio=4&crop-to-fit&sharpen&save-as=jpg&q=30 alt=''> |
|
||||
|
||||
Here is a list of all parameters that you can use together with `img.php`, grouped by its basic intent of usage.
|
||||
|
||||
|
||||
####Mandatory options and debugging
|
||||
|
||||
Option `src` is the only mandatory option. The other in this section is useful for debugging or deciding what version of the target image is used.
|
||||
|
||||
| Parameter | Explained |
|
||||
|----------------|----------------------------------------------|
|
||||
| `src` | Source image to use, mandatory. `src=img.png` or with subdirectory `src=dir/img.png`. |
|
||||
| `nc, no-cache` | Do not use the cached version, do all image processing and save a new image to cache. |
|
||||
| `so, skip-original`| Skip using the original image, always process image, create and use a cached version of the original image. |
|
||||
| `v, verbose` | Do verbose output and print out a log what happens. Good for debugging, analyzing the process and inspecting how the image is being processed. |
|
||||
| `json` | Output a JSON-representation of the image, useful for testing or optimizing when one wants to know the image dimensions, before using it. |
|
||||
|
||||
|
||||
|
||||
####Options for deciding width and height of target image
|
||||
|
||||
These options are all affecting the final dimensions, width and height, of the resulting image.
|
||||
|
||||
| Parameter | Explained |
|
||||
|----------------|----------------------------------------------|
|
||||
| `h, height` | `h=200` sets the width to be to max 200px. `h=25%` sets the height to max 25% of its original height. |
|
||||
| `w, width` | `w=200` sets the height to be max 200px. `w=100%` sets the width to max 100% of its original width. |
|
||||
| `ar, aspect-ratio` | Control target aspect ratio. Use together with either height or width or alone to base calculations on original image dimensions. This setting is used to calculate the resulting dimension for the image. `w=160&aspect-ratio=1.6` results in a height of 100px. Use `ar=!1.6` to inverse the ratio, useful for portrait images, compared to landscape images. |
|
||||
| `dpr, device-pixel-ratio` | Default value is 1, set to 2 when you are delivering the image to a high density screen, `dpr=2` or `dpr=1.4`. Its a easy way to say the image should have larger dimensions. The resulting image will be twice as large (or 1.4 times), keeping its aspect ratio. |
|
||||
|
||||
|
||||
|
||||
####Options for resize strategy
|
||||
|
||||
These options affect strategy to use when resizing an image into a target image that has both width and height set.
|
||||
|
||||
| Parameter | Explained |
|
||||
|----------------|----------------------------------------------|
|
||||
| `nr, no-ratio, stretch` | Do *not* keep aspect ratio when resizing and using both width & height constraints. Results in stretching the image, if needed, to fit in the resulting box. |
|
||||
| `cf, crop-to-fit` | Set together with both `h` and `w` to make the image fit into dimensions, and crop out the rest of the image. |
|
||||
| `ff, fill-to-fit` | Set together with both `h` and `w` to make the image fit into dimensions, and fill the rest using a background color. You can optionally supply a background color as this `ff=00ff00`, or `ff=00ff007f` when using the alpha channel. |
|
||||
| `nu, no-upscale` | Avoid smaller images from being upscaled to larger ones. Combine with `stretch`, `crop-to-fit` or `fill-to-fit` to get the smaller image centered on a larger canvas. The requested dimension for the target image are thereby met. |
|
||||
|
||||
|
||||
|
||||
####Options for cropping part of image
|
||||
|
||||
These options enable to decide what part of image to crop out.
|
||||
|
||||
| Parameter | Explained |
|
||||
|----------------|----------------------------------------------|
|
||||
| `a, area` | Define the area of the image to work with. Set `area=10,10,10,10` (top,right,bottom,left) to crop out the 10% of the outermost area. It works like an offset to define the part of the image you want to process. Its an alternative of using `crop`. |
|
||||
| `c, crop` | Crops an area from the original image, set width, height, start_x and start_y to define the area to crop, for example `crop=100,100,10,10` (`crop=width,height,start_x,start_y`). Left top corner is 0, 0. You can use `left`, `right` or `center` when setting start_x. You may use `top`, `bottom` or `center` when setting start_y. |
|
||||
|
||||
|
||||
|
||||
####General processing options
|
||||
|
||||
These options are general options affecting processing.
|
||||
|
||||
| Parameter | Explained |
|
||||
|----------------|----------------------------------------------|
|
||||
| `bgc, bg-color` | Set the backgroundcolor to use (if its needed). Use six hex digits as `bgc=00ff00` and 8 digits when using the alpha channel, as this `bgc=00ff007f`. The alpha value can be between 00 and 7f. |
|
||||
|
||||
|
||||
|
||||
####Processing of image before resizing
|
||||
|
||||
This option are executed *before* the image is resized.
|
||||
|
||||
| Parameter | Explained |
|
||||
|----------------|----------------------------------------------|
|
||||
| `s, scale` | Scale the image to a size proportional to a percentage of its original size, `scale=25` makes an image 25% of its original size and `size=200` doubles up the image size. Scale is applied before resizing and has no impact of the target width and height. |
|
||||
| `rb, rotate-before` | Rotate the image before its processed, send the angle as parameter `rb=45`. |
|
||||
| `aro, auto-rotate` | Auto rotate the image based on EXIF information (useful when using images from smartphones). |
|
||||
|
||||
|
||||
|
||||
####Processing of image after resizing
|
||||
|
||||
These options are executed *after* the image is resized.
|
||||
|
||||
| Parameter | Explained |
|
||||
|----------------|----------------------------------------------|
|
||||
| `ra, rotate-after`<br>`r, rotate` | Rotate the image after its processed, send the angle as parameter `ra=45`. |
|
||||
| `sharpen` | Appy a convolution filter that sharpens the image. |
|
||||
| `emboss` | Appy a convolution filter with an emboss effect. |
|
||||
| `blur` | Appy a convolution filter with a blur effect. |
|
||||
| `convolve` | Appy custom convolution filter as a 3x3 matrix, a divisor and offset, `convolve=0,-1,0,-1,5,-1,0,-1,0,1,0` sharpens the image. |
|
||||
| `convolve` | Use predefined convolution expression as `convolve=sharpen-alt` or a serie of convolutions as `convolve=draw,mean,motion`. These are supported out of the box: `lighten`, `darken`, `sharpen`, `sharpen-alt`, `emboss`, `emboss-alt`, `blur`, `gblur`, `edge`, `edge-alt`, `draw`, `mean`, `motion`. Add your own, or overwrite existing, in `img_config.php`. |
|
||||
| `f, filter` | Apply filter to image, `f=colorize,0,255,0,0` makes image more green. Supports all filters as defined in [PHP GD `imagefilter()`](http://php.net/manual/en/function.imagefilter.php). |
|
||||
| `f0, f1-f9` | Same as `filter`, just add more filters. Applied in order `f`, `f0-f9`. |
|
||||
| `sc, shortcut` | Save longer expressions in `img_config.php`. One place to change your favorite processing options, use as `sc=sepia` which is a shortcut for `&f=grayscale&f0=brightness,-10&f1=contrast,-20&f2=colorize,120,60,0,0&sharpen`. |
|
||||
|
||||
|
||||
|
||||
Documentation
|
||||
--------------------------------------
|
||||
|
||||
Read full documentation at:
|
||||
http://dbwebb.se/opensource/cimage
|
||||
|
||||
|
||||
|
||||
```
|
||||
.
|
||||
..: Copyright 2012-2015 by Mikael Roos (me@mikaelroos.se)
|
||||
```
|
||||
|
185
REVISION.md
Normal file
@@ -0,0 +1,185 @@
|
||||
Revision history
|
||||
=====================================
|
||||
|
||||
|
||||
v0.7.0-rc.1 (2015-02-10)
|
||||
-------------------------------------
|
||||
|
||||
* Always use password, setting in img_config.php, fix #78.
|
||||
* Resize gif keeping transparency #81.
|
||||
* Now returns statuscode 500 when something fails #55.
|
||||
* Three different modes: strict, production, development #44.
|
||||
* Three files for all-in-one `imgs.php`, `imgp.php`, `imgd.php` #73.
|
||||
* Change name of script all-in-one to `webroot/imgs.php` #73.
|
||||
* Combine all code into one singel script, `webroot/img_single.php` #73.
|
||||
* Disallow hotlinking/leeching by configuration #46.
|
||||
* Alias-name is without extension #47.
|
||||
* Option `alias` now requires `password` to work #47.
|
||||
* Support for option `password, pwd` to protect usage of `alias` and remote download.
|
||||
* Added support for option `alias` that creates a link to a cached version of the image #47.
|
||||
* Create cache directory for remote download if it does not exists.
|
||||
* Cleaned up `img_config.php` and introduced default values for almost all options #72.
|
||||
|
||||
|
||||
v0.6.2 (2015-01-14)
|
||||
-------------------------------------
|
||||
|
||||
* Added support for download of remote images #43.
|
||||
* Added autoloader.
|
||||
|
||||
|
||||
v0.6.1 (2015-01-08)
|
||||
-------------------------------------
|
||||
|
||||
* Adding compare-page for comparing images. Issue #20.
|
||||
* Added option `no-upscale, nu` as resizing strategy to decline upscaling of smaller images. Fix #61.
|
||||
* Minor change in `CImage::resize()`, crop now does imagecopy without resamling.
|
||||
* Correcting internal details for save-as and response json which indicated wrong colors. Fix #62.
|
||||
* Fixed fill-to-fit that failed when using aspect-ratio. Fix #52.
|
||||
* JSON returns correct values for resulting image. Fix #58.
|
||||
* Corrected behaviour for skip-original. Fix #60.
|
||||
|
||||
|
||||
v0.6 (2014-12-06)
|
||||
-------------------------------------
|
||||
|
||||
* Rewrote and added documentation.
|
||||
* Moved conolution expressesion from `img_config.php` to `CImage`.
|
||||
* Minor cleaning of properties in `CImage`. Fix #23.
|
||||
* Adding `webroot/htaccess` to show off how friendly urls can be created for `img.php`. Fix #45.
|
||||
* Added option `fill-to-fit, ff`. Fix #38.
|
||||
* Added option `shortcut, sc` to enable configuration of complex expressions. Fix #2.
|
||||
* Added support for custom convolutions. Fix #49.
|
||||
* Restructured testprograms. Fix #41.
|
||||
* Corrected json on PHP 5.3. Fix #42.
|
||||
* Improving template for tests in `webroot/tests` when testing out #40.
|
||||
* Adding testcase for #40.
|
||||
* Adding option `convolve` taking comma-separated list of 11 float-values, wraps and exposes `imageconvoluttion()`. #4
|
||||
* Adding option `dpr, device-pixel-ratio` which defaults to 1. Set to 2 to get a twice as large image. Useful for Retina displays. Basically a shortcut to enlarge the image.
|
||||
* Adding utility `cache.bash` to ease gathering stats on cache usage. #21
|
||||
* Cache-directory can now be readonly and serve all cached files, still failing when need to save files. #5
|
||||
* Cache now uses same file extension as original image #37.
|
||||
* Can output image as json format using `json` #11.
|
||||
|
||||
|
||||
v0.5.3 (2014-11-21)
|
||||
-------------------------------------
|
||||
|
||||
* Support filenames of uppercase JPEG, JPG, PNG and GIF, as proposed in #37.
|
||||
* Changing `CImage::output()` as proposed in #37.
|
||||
* Adding security check that image filename is always below the path `image_path` as specified in `img_config.php` #37.
|
||||
* Adding configuration item in `img_config.php` for setting valid characters in image filename.
|
||||
* Moving `webroot/test*` into directory `webroot/test`.
|
||||
* `webroot/check_system.php` now outputs if extension for exif is loaded.
|
||||
* Broke API when `initDimensions()` split into two methods, new `initDimensions()` and `loadImageDetails()`.
|
||||
* Added `autoRotate, aro` to auto rotate image based on EXIF information.
|
||||
* Added `bgColor, bgc` to use as backgroundcolor when needing a filler color, for example rotate 45.
|
||||
* Added `rotateBefore, rb` to rotate image a certain angle before processing.
|
||||
* Added `rotateAfter, ra` to rotate image a certain angle after processing.
|
||||
* Cleaned up code formatting, removed trailing spaces.
|
||||
* Removed @ from opening images, better to display correct warning when failing #34, but put it back again.
|
||||
* Setting gd.jpeg_ignore_warning to true as default #34.
|
||||
* `webroot/check_system.php` now outputs version of PHP and GD.
|
||||
* #32 correctly send 404 header when serving an error message.
|
||||
* Trying to verify issue #29, but can not.
|
||||
* Adding structure for testprograms together with, use `webroot/test_issue29.php` as sample.
|
||||
* Improving code formatting.
|
||||
* Moving parts of verbose output from img.php to CImage.php.
|
||||
|
||||
|
||||
v0.5.2 (2014-04-01)
|
||||
-------------------------------------
|
||||
|
||||
* Correcting issue #26 providing error message when not using postprocessing.
|
||||
* Correcting issue #27 warning of default timezone.
|
||||
* Removed default $config options in `img.php`, was not used, all configuration should be in `img_config.php`.
|
||||
* Verified known bug - sharpen acts as blur in PHP 5.5.9 and 5.5.10 #28
|
||||
|
||||
|
||||
v0.5.1 (2014-02-12)
|
||||
-------------------------------------
|
||||
|
||||
* Display image in README-file.
|
||||
* Create an empty `cache` directory as part of repo.
|
||||
|
||||
|
||||
v0.5 (2014-02-12)
|
||||
-------------------------------------
|
||||
|
||||
* Change constant name `CImage::PNG_QUALITY_DEFAULT` to `CImage::PNG_COMPRESSION_DEFAULT`.
|
||||
* Split JPEG quality and PNG compression, `CImage->quality` and `CImage->compression`
|
||||
* Changed `img.php` parameter name `d, deflate` to `co, compress`.
|
||||
* Separating configuration issues from `img.php` to `img_config.php`.
|
||||
* Format code according to PSR-2.
|
||||
* Disabled post-processing JPEG and PNG as default.
|
||||
* This version is supporting PHP 5.3, later versions will require 5.5 or later.
|
||||
* Using GitHub issue tracking for feature requests and planning.
|
||||
* Rewrote [the manual](http://dbwebb.se/opensource/cimage).
|
||||
* Created directory `webroot` and moved some files there.
|
||||
|
||||
|
||||
v0.4.1 (2014-01-27)
|
||||
-------------------------------------
|
||||
|
||||
* Changed => to == on Modified-Since.
|
||||
* Always send Last-Modified-Header.
|
||||
* Added `htmlentities()` to verbose output.
|
||||
* Fixed support for jpeg, not only jpg.
|
||||
* Fixed crop whole image by setting crop=0,0,0,0
|
||||
* Use negative values for crop width & height to base calulation on original width/height and withdraw selected amount.
|
||||
* Correcting jpeg when setting quality.
|
||||
* Removed obsolete reference to `$newName` in `CImage::__construct()` (issue 1).
|
||||
|
||||
|
||||
v0.4 (2013-10-08)
|
||||
-------------------------------------
|
||||
|
||||
* Improved support for pre-defined sizes.
|
||||
* Adding grid column size as predefined size, c1-c24 for a 24 column grid. Configure in `img.php`.
|
||||
* Corrected error on naming cache-files using subdir.
|
||||
* Corrected calculation error on width & height for crop-to-fit.
|
||||
* Adding effects for sharpen, emboss and blur through imageconvolution using matrixes.
|
||||
* crop-to-fit, add parameter for offset x and y to enable to define which area is the, implemented as area.
|
||||
* Support for resizing opaque images.
|
||||
* Center of the image from which the crop is done. Improved usage of area to crop.
|
||||
* Added support for % in width & height.
|
||||
* Added aspect-ratio.
|
||||
* Added scale.
|
||||
* Quality for PNG images is now knows as deflate.
|
||||
* Added palette to create images with max 256 colors.
|
||||
* Added usage of all parameters to README.md
|
||||
* Added documentation here http://dbwebb.se/opensource/cimage
|
||||
* Adding `.gitignore`
|
||||
* Re-adding `cache` directory
|
||||
|
||||
|
||||
v0.3 (2012-10-02)
|
||||
-------------------------------------
|
||||
|
||||
* Added crop. Can crop a area (`width`, `height`, `start_x`, `start_y`) from the original
|
||||
image.
|
||||
* Corrected to make the 304 Not Modified header work.
|
||||
* Predefined sizes can be configured for width in `img.php`.
|
||||
* Corrected to make crop work with width or height in combination with crop-to-fit.
|
||||
|
||||
|
||||
v0.2 (2012-05-09)
|
||||
-------------------------------------
|
||||
|
||||
* Implemented filters as in http://php.net/manual/en/function.imagefilter.php
|
||||
* Changed `crop` to `crop_to_fit`, works the same way.
|
||||
* Changed arguments and sends them in array.
|
||||
* Added quality-setting.
|
||||
* Added testcases for above.
|
||||
|
||||
|
||||
v0.1.1 (2012-04-27)
|
||||
-------------------------------------
|
||||
|
||||
* Corrected calculation where both width and height were set.
|
||||
|
||||
|
||||
v0.1 (2012-04-25)
|
||||
-------------------------------------
|
||||
|
||||
* Initial release after rewriting some older code doing the same, but not that good and flexible.
|
23
autoload.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
/**
|
||||
* Autoloader for CImage and related class files.
|
||||
*
|
||||
*/
|
||||
//include __DIR__ . "/../CHttpGet.php";
|
||||
//include __DIR__ . "/../CRemoteImage.php";
|
||||
//include __DIR__ . "/../CImage.php";
|
||||
|
||||
/**
|
||||
* Autoloader for classes.
|
||||
*
|
||||
* @param string $class the fully-qualified class name.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
spl_autoload_register(function ($class) {
|
||||
//$path = CIMAGE_SOURCE_PATH . "/{$class}.php";
|
||||
$path = __DIR__ . "/{$class}.php";
|
||||
if(is_file($path)) {
|
||||
require($path);
|
||||
}
|
||||
});
|
36
cache.bash
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# Specify the utilities used
|
||||
#
|
||||
ECHO="printf"
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Main, start by checking basic usage
|
||||
#
|
||||
if [ $# -lt 1 ]
|
||||
then
|
||||
$ECHO "Usage: $0 [cache-dir]\n"
|
||||
exit 1
|
||||
elif [ ! -d "$1" ]; then
|
||||
$ECHO "Usage: $0 [cache-dir]\n"
|
||||
$ECHO "$1 is not a directory.\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Print out details on cache-directory
|
||||
#
|
||||
$ECHO "Total size: $( du -sh $1 | cut -f1 )"
|
||||
$ECHO "\nNumber of files: $( find $1 | wc -l )"
|
||||
$ECHO "\n\nTop-5 largest files:\n"
|
||||
$ECHO "$( du -s $1/* | sort -nr | head -5 )"
|
||||
$ECHO "\n\nLast-5 created files:\n"
|
||||
$ECHO "$( find $1/* -printf '%TY-%Tm-%Td %TH:%TM %p\n' | sort -r | head -5 )"
|
||||
$ECHO "\n\nLast-5 accessed files:\n"
|
||||
$ECHO "$( find $1/* -printf '%AY-%Am-%Ad %AH:%AM %f\n' | sort -r | head -5 )"
|
||||
$ECHO "\n"
|
1
cache/README.md
vendored
Normal file
@@ -0,0 +1 @@
|
||||
This directory must be writable by the webserver.
|
74
create-img-single.bash
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# Paths and settings
|
||||
#
|
||||
TARGET_D="webroot/imgd.php"
|
||||
TARGET_P="webroot/imgp.php"
|
||||
TARGET_S="webroot/imgs.php"
|
||||
NEWLINES="\n\n\n"
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Specify the utilities used
|
||||
#
|
||||
ECHO="printf"
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Main, start by checking basic usage
|
||||
#
|
||||
if [ $# -gt 0 ]
|
||||
then
|
||||
$ECHO "Usage: $0\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Print out details on cache-directory
|
||||
#
|
||||
$ECHO "Creating '$TARGET_D', '$TARGET_P' and '$TARGET_S' by combining the following files:"
|
||||
$ECHO "\n"
|
||||
$ECHO "\n webroot/img_header.php"
|
||||
$ECHO "\n CHttpGet.php"
|
||||
$ECHO "\n CRemoteImage.php"
|
||||
$ECHO "\n CImage.php"
|
||||
$ECHO "\n webroot/img.php"
|
||||
$ECHO "\n"
|
||||
$ECHO "\n'$TARGET_D' is for development mode."
|
||||
$ECHO "\n'$TARGET_P' is for production mode (default mode)."
|
||||
$ECHO "\n'$TARGET_S' is for strict mode."
|
||||
$ECHO "\n"
|
||||
|
||||
$ECHO "\nPress enter to continue. "
|
||||
read answer
|
||||
|
||||
|
||||
#
|
||||
# Create the $TARGET_? files
|
||||
#
|
||||
cat webroot/img_header.php > $TARGET_P
|
||||
cat webroot/img_header.php | sed "s|//'mode' => 'production',|'mode' => 'development',|" > $TARGET_D
|
||||
cat webroot/img_header.php | sed "s|//'mode' => 'production',|'mode' => 'development',|" > $TARGET_S
|
||||
|
||||
$ECHO "$NEWLINES" | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
||||
|
||||
tail -n +2 CHttpGet.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 CRemoteImage.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
|
||||
|
||||
tail -n +2 webroot/img.php | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
||||
$ECHO "$NEWLINES" | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
|
||||
|
||||
$ECHO "\nDone."
|
||||
$ECHO "\n"
|
||||
$ECHO "\n"
|
34
img.php
@@ -1,34 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Resize images on the fly using cache.
|
||||
*
|
||||
*/
|
||||
error_reporting(-1);
|
||||
set_time_limit(20);
|
||||
|
||||
// Append ending slash
|
||||
$pathToImages = __DIR__.'/img/';
|
||||
$pathToCache = __DIR__.'/cache/';
|
||||
|
||||
// Get input from querystring
|
||||
$srcImage = isset($_GET['src']) ? $pathToImages . basename($_GET['src']) : null;
|
||||
$newWidth = isset($_GET['width']) ? $_GET['width'] : (isset($_GET['w']) ? $_GET['w'] : null);
|
||||
$newHeight = isset($_GET['height']) ? $_GET['height'] : (isset($_GET['h']) ? $_GET['h'] : null);
|
||||
$keepRatio = isset($_GET['no-ratio']) ? false : true; // Keep Aspect Ratio?
|
||||
$crop = isset($_GET['crop']) ? true : false; // Crop image?
|
||||
|
||||
// Do some sanity checks
|
||||
!preg_match('/^[\w-\.]+$/', $srcImage) or die('Filename contains invalid characters.');
|
||||
if(isset($newWidth)) {
|
||||
$newWidth < 1000 or die('To large width.');
|
||||
$newWidth > 10 or die('To small width.');
|
||||
}
|
||||
if(isset($newHeight)) {
|
||||
$newHeight < 1000 or die('To large height.');
|
||||
$newHeight > 10 or die('To small height.');
|
||||
}
|
||||
|
||||
// Create the image object
|
||||
require(__DIR__.'/CImage.php');
|
||||
$img = new CImage($srcImage, $newWidth, $newHeight, $keepRatio, $crop, $pathToCache);
|
||||
$img->ResizeAndOutput();
|
42
test.php
@@ -1,42 +0,0 @@
|
||||
<!doctype html>
|
||||
<head>
|
||||
<meta charset='utf-8'/>
|
||||
<title>Testing img resizing using CImage.php</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Testing <code>CImage.php</code> through <code>img.php</code></h1>
|
||||
<p>You can test any variation of resizing the images through <a href='img.php?src=wider.jpg&w=200&h=200'>img.php?src=wider.jpg&w=200&h=200</a> or <a href='img.php?src=higher.jpg&w=200&h=200'>img.php?src=higher.jpg&w=200&h=200</a></p>
|
||||
<p>Supported arguments throught the querystring are:</p>
|
||||
<ul>
|
||||
<li>h, height: h=200 sets the height to 200px.
|
||||
<li>w, width: w=200 sets the width to 200px.
|
||||
<li>crop: together with both h & w makes the image fit in the box.
|
||||
<li>no-ratio: do not keep aspect ratio.
|
||||
</ul>
|
||||
<p>Sourcecode and issues on github: <a href='https://github.com/mosbth/cimage'>https://github.com/mosbth/cimage</a></p>
|
||||
<p>Mikael Roos (mos@dbwebb.se)</p>
|
||||
|
||||
<h2>Testcases</h2>
|
||||
<table>
|
||||
<caption>Test cases</caption>
|
||||
<thead><tr><th>Testcase:</th><th>Result:</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>Original image of wider.jpg.</td><td><img src='img.php?src=wider.jpg' /></td></tr>
|
||||
<tr><td>wider.jpg max width 200.</td><td><img src='img.php?src=wider.jpg&w=200' /></td></tr>
|
||||
<tr><td>wider.jpg max height 200.</td><td><img src='img.php?src=wider.jpg&h=200' /></td></tr>
|
||||
<tr><td>wider.jpg max width 200 and max height 200.</td><td><img src='img.php?src=wider.jpg&w=200&h=200' /></td></tr>
|
||||
<tr><td>wider.jpg max width 200 and max height 200 and no-ratio.</td><td><img src='img.php?src=wider.jpg&w=200&h=200&no-ratio' /></td></tr>
|
||||
<tr><td>wider.jpg max width 200 and max height 200 and cropped.</td><td><img src='img.php?src=wider.jpg&w=200&h=200&crop' /></td></tr>
|
||||
<tr><td>wider.jpg max width 200 and max height 100 and cropped.</td><td><img src='img.php?src=wider.jpg&w=200&h=100&crop' /></td></tr>
|
||||
<tr><td>Original image of higher.jpg.</td><td><img src='img.php?src=higher.jpg' /></td></tr>
|
||||
<tr><td>higher.jpg max width 200.</td><td><img src='img.php?src=higher.jpg&w=200' /></td></tr>
|
||||
<tr><td>higher.jpg max height 200.</td><td><img src='img.php?src=higher.jpg&h=200' /></td></tr>
|
||||
<tr><td>higher.jpg max width 200 and max height 200.</td><td><img src='img.php?src=higher.jpg&w=200&h=200' /></td></tr>
|
||||
<tr><td>higher.jpg max width 200 and max height 200 and no-ratio.</td><td><img src='img.php?src=higher.jpg&w=200&h=200&no-ratio' /></td></tr>
|
||||
<tr><td>higher.jpg max width 200 and max height 200 and cropped.</td><td><img src='img.php?src=higher.jpg&w=200&h=200&crop' /></td></tr>
|
||||
<tr><td>higher.jpg max width 200 and max height 100 and cropped.</td><td><img src='img.php?src=higher.jpg&w=200&h=100&crop' /></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</body>
|
||||
</html>
|
15
webroot/check_system.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
echo 'Current PHP version: ' . phpversion() . '<br><br>';
|
||||
|
||||
echo 'Running on: ' . $_SERVER['SERVER_SOFTWARE'] . '<br><br>';
|
||||
|
||||
$no = extension_loaded('gd') ? null : 'NOT';
|
||||
echo "Extension gd is $no loaded.<br>";
|
||||
|
||||
$no = extension_loaded('exif') ? null : 'NOT';
|
||||
echo "Extension exif is $no loaded.<br>";
|
||||
|
||||
if (!$no) {
|
||||
echo "<pre>", var_dump(gd_info()), "</pre>";
|
||||
}
|
13
webroot/compare/compare-test.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
$script = <<<EOD
|
||||
CImage.compare({
|
||||
"input1": "../img.php?src=car.png",
|
||||
"input2": "../img.php?src=car.png&sharpen",
|
||||
"input3": "../img.php?src=car.png&blur",
|
||||
"input4": "../img.php?src=car.png&emboss",
|
||||
"json": true,
|
||||
"stack": false
|
||||
});
|
||||
EOD;
|
||||
|
||||
include __DIR__ . "/compare.php";
|
106
webroot/compare/compare.php
Normal file
@@ -0,0 +1,106 @@
|
||||
<!doctype html>
|
||||
<html lang=en>
|
||||
<head>
|
||||
<style>
|
||||
|
||||
body {
|
||||
}
|
||||
|
||||
input[type=text] {
|
||||
width: 400px;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#wrap {
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
|
||||
}
|
||||
|
||||
.stack {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.area {
|
||||
float: left;
|
||||
padding: 1em;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.top {
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Compare images</h1>
|
||||
<p>Add link to images and visually compare them. Change the link och press return to load the image. <a href="http://dbwebb.se/opensource/cimage">Read more...</a></p>
|
||||
|
||||
<form>
|
||||
<p>
|
||||
<label>Image 1: <input type="text" id="input1" data-id="1"></label> <img id="thumb1"></br>
|
||||
<label>Image 2: <input type="text" id="input2" data-id="2"></label> <img id="thumb2"></br>
|
||||
<label>Image 3: <input type="text" id="input3" data-id="3"></label> <img id="thumb3"></br>
|
||||
<label>Image 4: <input type="text" id="input4" data-id="4"></label> <img id="thumb4"></br>
|
||||
<label><input type="checkbox" id="viewDetails">Hide image details?</label><br/>
|
||||
<label><input type="checkbox" id="stack">Stack images?</label>
|
||||
</p>
|
||||
</form>
|
||||
|
||||
<div id="buttonWrap" class="hidden">
|
||||
<button id="button1" class="button" data-id="1">Image 1</button>
|
||||
<button id="button2" class="button" data-id="2">Image 2</button>
|
||||
<button id="button3" class="button" data-id="3">Image 3</button>
|
||||
<button id="button4" class="button" data-id="4">Image 4</button>
|
||||
</div>
|
||||
|
||||
<div id="wrap">
|
||||
|
||||
<div id="area1" class="area">
|
||||
<code>Image 1</code><br>
|
||||
<img id="img1">
|
||||
<pre id="json1" class="json"></pre>
|
||||
</div>
|
||||
|
||||
<div id="area2" class="area">
|
||||
<code>Image 2</code><br>
|
||||
<img id="img2">
|
||||
<pre id="json2" class="json"></pre>
|
||||
</div>
|
||||
|
||||
<div id="area3" class="area">
|
||||
<code>Image 3</code><br>
|
||||
<img id="img3">
|
||||
<pre id="json3" class="json"></pre>
|
||||
</div>
|
||||
|
||||
<div id="area4" class="area">
|
||||
<code>Image 4</code><br>
|
||||
<img id="img4">
|
||||
<pre id="json4" class="json"></pre>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
|
||||
<script src="../js/cimage.js"></script>
|
||||
<script>
|
||||
<?php
|
||||
if (isset($script)) {
|
||||
echo $script;
|
||||
} else {
|
||||
echo "CImage.compare({});";
|
||||
} ?>
|
||||
</script>
|
||||
|
||||
</html>
|
17
webroot/htaccess
Normal file
@@ -0,0 +1,17 @@
|
||||
#
|
||||
# Rewrite to have friendly urls to img.php, edit it to suite your environment.
|
||||
#
|
||||
# The example is set up as following.
|
||||
#
|
||||
# img A directory where all images are stored
|
||||
# img/me.jpg Access a image as usually.
|
||||
# img/img.php This is where I choose to place img.php (and img_config.php).
|
||||
# image/me.jpg Access a image though img.php using htaccess rewrite.
|
||||
# image/me.jpg?w=300 Using options to img.php.
|
||||
#
|
||||
# Subdirectories also work.
|
||||
# img/me/me.jpg Direct access to the image.
|
||||
# image/me/me.jpg Accessed through img.php.
|
||||
# image/me/me.jpg?w=300 Using options to img.php.
|
||||
#
|
||||
RewriteRule ^image/(.*)$ img/img.php?src=$1 [QSA,NC,L]
|
912
webroot/img.php
Normal file
@@ -0,0 +1,912 @@
|
||||
<?php
|
||||
/**
|
||||
* Resize and crop images on the fly, store generated images in a cache.
|
||||
*
|
||||
* @author Mikael Roos mos@dbwebb.se
|
||||
* @example http://dbwebb.se/opensource/cimage
|
||||
* @link https://github.com/mosbth/cimage
|
||||
*
|
||||
*/
|
||||
|
||||
$version = "v0.7.0-rc.1 (2015-02-10)";
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Default configuration options, can be overridden in own config-file.
|
||||
*
|
||||
* @param string $msg to display.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function errorPage($msg)
|
||||
{
|
||||
global $mode;
|
||||
|
||||
header("HTTP/1.0 500 Internal Server Error");
|
||||
|
||||
if ($mode == 'development') {
|
||||
die("[img.php] $msg");
|
||||
} else {
|
||||
error_log("[img.php] $msg");
|
||||
die("HTTP/1.0 500 Internal Server Error");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Custom exception handler.
|
||||
*/
|
||||
set_exception_handler(function ($exception) {
|
||||
errorPage("<p><b>img.php: Uncaught exception:</b> <p>" . $exception->getMessage() . "</p><pre>" . $exception->getTraceAsString(), "</pre>");
|
||||
});
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get input from query string or return default value if not set.
|
||||
*
|
||||
* @param mixed $key as string or array of string values to look for in $_GET.
|
||||
* @param mixed $default value to return when $key is not set in $_GET.
|
||||
*
|
||||
* @return mixed value from $_GET or default value.
|
||||
*/
|
||||
function get($key, $default = null)
|
||||
{
|
||||
if (is_array($key)) {
|
||||
foreach ($key as $val) {
|
||||
if (isset($_GET[$val])) {
|
||||
return $_GET[$val];
|
||||
}
|
||||
}
|
||||
} elseif (isset($_GET[$key])) {
|
||||
return $_GET[$key];
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get input from query string and set to $defined if defined or else $undefined.
|
||||
*
|
||||
* @param mixed $key as string or array of string values to look for in $_GET.
|
||||
* @param mixed $defined value to return when $key is set in $_GET.
|
||||
* @param mixed $undefined value to return when $key is not set in $_GET.
|
||||
*
|
||||
* @return mixed value as $defined or $undefined.
|
||||
*/
|
||||
function getDefined($key, $defined, $undefined)
|
||||
{
|
||||
return get($key) === null ? $undefined : $defined;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get value from config array or default if key is not set in config array.
|
||||
*
|
||||
* @param string $key the key in the config array.
|
||||
* @param mixed $default value to be default if $key is not set in config.
|
||||
*
|
||||
* @return mixed value as $config[$key] or $default.
|
||||
*/
|
||||
function getConfig($key, $default)
|
||||
{
|
||||
global $config;
|
||||
return isset($config[$key])
|
||||
? $config[$key]
|
||||
: $default;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Log when verbose mode, when used without argument it returns the result.
|
||||
*
|
||||
* @param string $msg to log.
|
||||
*
|
||||
* @return void or array.
|
||||
*/
|
||||
function verbose($msg = null)
|
||||
{
|
||||
global $verbose;
|
||||
static $log = array();
|
||||
|
||||
if (!$verbose) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_null($msg)) {
|
||||
return $log;
|
||||
}
|
||||
|
||||
$log[] = $msg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get configuration options from file, if the file exists, else use $config
|
||||
* if its defined or create an empty $config.
|
||||
*/
|
||||
$configFile = __DIR__.'/'.basename(__FILE__, '.php').'_config.php';
|
||||
|
||||
if (is_file($configFile)) {
|
||||
$config = require $configFile;
|
||||
} else if (!isset($config)) {
|
||||
$config = array();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* verbose, v - do a verbose dump of what happens
|
||||
*/
|
||||
$verbose = getDefined(array('verbose', 'v'), true, false);
|
||||
verbose("img.php version = $version");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set mode as strict, production or development.
|
||||
* Default is production environment.
|
||||
*/
|
||||
$mode = getConfig('mode', 'production');
|
||||
|
||||
// Settings for any mode
|
||||
set_time_limit(20);
|
||||
ini_set('gd.jpeg_ignore_warning', 1);
|
||||
|
||||
if (!extension_loaded('gd')) {
|
||||
errorPage("Extension gd is nod loaded.");
|
||||
}
|
||||
|
||||
// Specific settings for each mode
|
||||
if ($mode == 'strict') {
|
||||
|
||||
error_reporting(0);
|
||||
ini_set('display_errors', 0);
|
||||
ini_set('log_errors', 1);
|
||||
$verbose = false;
|
||||
|
||||
} else if ($mode == 'production') {
|
||||
|
||||
error_reporting(-1);
|
||||
ini_set('display_errors', 0);
|
||||
ini_set('log_errors', 1);
|
||||
$verbose = false;
|
||||
|
||||
} else if ($mode == 'development') {
|
||||
|
||||
error_reporting(-1);
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('log_errors', 0);
|
||||
|
||||
} else {
|
||||
errorPage("Unknown mode: $mode");
|
||||
}
|
||||
|
||||
verbose("mode = $mode");
|
||||
verbose("error log = " . ini_get('error_log'));
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set default timezone if not set or if its set in the config-file.
|
||||
*/
|
||||
$defaultTimezone = getConfig('default_timezone', null);
|
||||
|
||||
if ($defaultTimezone) {
|
||||
date_default_timezone_set($defaultTimezone);
|
||||
} else if (!ini_get('default_timezone')) {
|
||||
date_default_timezone_set('UTC');
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Check if passwords are configured, used and match.
|
||||
* Options decide themself if they require passwords to be used.
|
||||
*/
|
||||
$pwdConfig = getConfig('password', false);
|
||||
$pwdAlways = getConfig('password_always', false);
|
||||
$pwd = get(array('password', 'pwd'), null);
|
||||
|
||||
// Check if passwords match, if configured to use passwords
|
||||
$passwordMatch = null;
|
||||
if ($pwdAlways) {
|
||||
|
||||
$passwordMatch = ($pwdConfig === $pwd);
|
||||
if (!$passwordMatch) {
|
||||
errorPage("Password required and does not match or exists.");
|
||||
}
|
||||
|
||||
} elseif ($pwdConfig && $pwd) {
|
||||
|
||||
$passwordMatch = ($pwdConfig === $pwd);
|
||||
}
|
||||
|
||||
verbose("password match = $passwordMatch");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Prevent hotlinking, leeching, of images by controlling who access them
|
||||
* from where.
|
||||
*
|
||||
*/
|
||||
$allowHotlinking = getConfig('allow_hotlinking', true);
|
||||
$hotlinkingWhitelist = getConfig('hotlinking_whitelist', array());
|
||||
|
||||
$serverName = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : null;
|
||||
$referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : null;
|
||||
$refererHost = parse_url($referer, PHP_URL_HOST);
|
||||
|
||||
if (!$allowHotlinking) {
|
||||
if ($passwordMatch) {
|
||||
; // Always allow when password match
|
||||
} else if ($passwordMatch === false) {
|
||||
errorPage("Hotlinking/leeching not allowed when password missmatch.");
|
||||
} else if (!$referer) {
|
||||
errorPage("Hotlinking/leeching not allowed and referer is missing.");
|
||||
} else if (strcmp($serverName, $refererHost) == 0) {
|
||||
; // Allow when serverName matches refererHost
|
||||
} else if (!empty($hotlinkingWhitelist)) {
|
||||
|
||||
$allowedByWhitelist = false;
|
||||
foreach ($hotlinkingWhitelist as $val) {
|
||||
if (preg_match($val, $refererHost)) {
|
||||
$allowedByWhitelist = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$allowedByWhitelist) {
|
||||
errorPage("Hotlinking/leeching not allowed by whitelist.");
|
||||
}
|
||||
|
||||
} else {
|
||||
errorPage("Hotlinking/leeching not allowed.");
|
||||
}
|
||||
}
|
||||
|
||||
verbose("allow_hotlinking = $allowHotlinking");
|
||||
verbose("referer = $referer");
|
||||
verbose("referer host = $refererHost");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the source files.
|
||||
*/
|
||||
$autoloader = getConfig('autoloader', false);
|
||||
$cimageClass = getConfig('cimage_class', false);
|
||||
|
||||
if ($autoloader) {
|
||||
require $autoloader;
|
||||
} else if ($cimageClass) {
|
||||
require $cimageClass;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create the class for the image.
|
||||
*/
|
||||
$img = new CImage();
|
||||
$img->setVerbose($verbose);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Allow or disallow remote download of images from other servers.
|
||||
* Passwords apply if used.
|
||||
*
|
||||
*/
|
||||
$allowRemote = getConfig('remote_allow', false);
|
||||
|
||||
if ($allowRemote && $passwordMatch !== false) {
|
||||
$pattern = getConfig('remote_pattern', null);
|
||||
$img->setRemoteDownload($allowRemote, $pattern);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* shortcut, sc - extend arguments with a constant value, defined
|
||||
* in config-file.
|
||||
*/
|
||||
$shortcut = get(array('shortcut', 'sc'), null);
|
||||
$shortcutConfig = getConfig('shortcut', array(
|
||||
'sepia' => "&f=grayscale&f0=brightness,-10&f1=contrast,-20&f2=colorize,120,60,0,0&sharpen",
|
||||
));
|
||||
|
||||
verbose("shortcut = $shortcut");
|
||||
|
||||
if (isset($shortcut)
|
||||
&& isset($shortcutConfig[$shortcut])) {
|
||||
|
||||
parse_str($shortcutConfig[$shortcut], $get);
|
||||
verbose("shortcut-constant = {$shortcutConfig[$shortcut]}");
|
||||
$_GET = array_merge($_GET, $get);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* src - the source image file.
|
||||
*/
|
||||
$srcImage = get('src')
|
||||
or errorPage('Must set src-attribute.');
|
||||
|
||||
// Check for valid/invalid characters
|
||||
$imagePath = getConfig('image_path', __DIR__ . '/img/');
|
||||
$imagePathConstraint = getConfig('image_path_constraint', true);
|
||||
$validFilename = getConfig('valid_filename', '#^[a-z0-9A-Z-/_\.:]+$#');
|
||||
|
||||
preg_match($validFilename, $srcImage)
|
||||
or errorPage('Filename contains invalid characters.');
|
||||
|
||||
if ($allowRemote && $img->isRemoteSource($srcImage)) {
|
||||
|
||||
// If source is a remote file, ignore local file checks.
|
||||
|
||||
} else if ($imagePathConstraint) {
|
||||
|
||||
// Check that the image is a file below the directory 'image_path'.
|
||||
$pathToImage = realpath($imagePath . $srcImage);
|
||||
$imageDir = realpath($imagePath);
|
||||
|
||||
is_file($pathToImage)
|
||||
or errorPage(
|
||||
'Source image is not a valid file, check the filename and that a
|
||||
matching file exists on the filesystem.'
|
||||
);
|
||||
|
||||
substr_compare($imageDir, $pathToImage, 0, strlen($imageDir)) == 0
|
||||
or errorPage(
|
||||
'Security constraint: Source image is not below the directory "image_path"
|
||||
as specified in the config file img_config.php.'
|
||||
);
|
||||
}
|
||||
|
||||
verbose("src = $srcImage");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Manage size constants from config file, use constants to replace values
|
||||
* for width and height.
|
||||
*/
|
||||
$sizeConstant = getConfig('size_constant', function () {
|
||||
|
||||
// Set sizes to map constant to value, easier to use with width or height
|
||||
$sizes = array(
|
||||
'w1' => 613,
|
||||
'w2' => 630,
|
||||
);
|
||||
|
||||
// Add grid column width, useful for use as predefined size for width (or height).
|
||||
$gridColumnWidth = 30;
|
||||
$gridGutterWidth = 10;
|
||||
$gridColumns = 24;
|
||||
|
||||
for ($i = 1; $i <= $gridColumns; $i++) {
|
||||
$sizes['c' . $i] = ($gridColumnWidth + $gridGutterWidth) * $i - $gridGutterWidth;
|
||||
}
|
||||
|
||||
return $sizes;
|
||||
});
|
||||
|
||||
$sizes = call_user_func($sizeConstant);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* width, w - set target width, affecting the resulting image width, height and resize options
|
||||
*/
|
||||
$newWidth = get(array('width', 'w'));
|
||||
$maxWidth = getConfig('max_width', 2000);
|
||||
|
||||
// Check to replace predefined size
|
||||
if (isset($sizes[$newWidth])) {
|
||||
$newWidth = $sizes[$newWidth];
|
||||
}
|
||||
|
||||
// Support width as % of original width
|
||||
if ($newWidth[strlen($newWidth)-1] == '%') {
|
||||
is_numeric(substr($newWidth, 0, -1))
|
||||
or errorPage('Width % not numeric.');
|
||||
} else {
|
||||
is_null($newWidth)
|
||||
or ($newWidth > 10 && $newWidth <= $maxWidth)
|
||||
or errorPage('Width out of range.');
|
||||
}
|
||||
|
||||
verbose("new width = $newWidth");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* height, h - set target height, affecting the resulting image width, height and resize options
|
||||
*/
|
||||
$newHeight = get(array('height', 'h'));
|
||||
$maxHeight = getConfig('max_height', 2000);
|
||||
|
||||
// Check to replace predefined size
|
||||
if (isset($sizes[$newHeight])) {
|
||||
$newHeight = $sizes[$newHeight];
|
||||
}
|
||||
|
||||
// height
|
||||
if ($newHeight[strlen($newHeight)-1] == '%') {
|
||||
is_numeric(substr($newHeight, 0, -1))
|
||||
or errorPage('Height % out of range.');
|
||||
} else {
|
||||
is_null($newHeight)
|
||||
or ($newHeight > 10 && $newHeight <= $maxHeight)
|
||||
or errorPage('Hight out of range.');
|
||||
}
|
||||
|
||||
verbose("new height = $newHeight");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* aspect-ratio, ar - affecting the resulting image width, height and resize options
|
||||
*/
|
||||
$aspectRatio = get(array('aspect-ratio', 'ar'));
|
||||
$aspectRatioConstant = getConfig('aspect_ratio_constant', function () {
|
||||
return array(
|
||||
'3:1' => 3/1,
|
||||
'3:2' => 3/2,
|
||||
'4:3' => 4/3,
|
||||
'8:5' => 8/5,
|
||||
'16:10' => 16/10,
|
||||
'16:9' => 16/9,
|
||||
'golden' => 1.618,
|
||||
);
|
||||
});
|
||||
|
||||
// Check to replace predefined aspect ratio
|
||||
$aspectRatios = call_user_func($aspectRatioConstant);
|
||||
$negateAspectRatio = ($aspectRatio[0] == '!') ? true : false;
|
||||
$aspectRatio = $negateAspectRatio ? substr($aspectRatio, 1) : $aspectRatio;
|
||||
|
||||
if (isset($aspectRatios[$aspectRatio])) {
|
||||
$aspectRatio = $aspectRatios[$aspectRatio];
|
||||
}
|
||||
|
||||
if ($negateAspectRatio) {
|
||||
$aspectRatio = 1 / $aspectRatio;
|
||||
}
|
||||
|
||||
is_null($aspectRatio)
|
||||
or is_numeric($aspectRatio)
|
||||
or errorPage('Aspect ratio out of range');
|
||||
|
||||
verbose("aspect ratio = $aspectRatio");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* crop-to-fit, cf - affecting the resulting image width, height and resize options
|
||||
*/
|
||||
$cropToFit = getDefined(array('crop-to-fit', 'cf'), true, false);
|
||||
|
||||
verbose("crop to fit = $cropToFit");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set default background color from config file.
|
||||
*/
|
||||
$backgroundColor = getConfig('background_color', null);
|
||||
|
||||
if ($backgroundColor) {
|
||||
$img->setDefaultBackgroundColor($backgroundColor);
|
||||
verbose("Using default background_color = $backgroundColor");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* bgColor - Default background color to use
|
||||
*/
|
||||
$bgColor = get(array('bgColor', 'bg-color', 'bgc'), null);
|
||||
|
||||
verbose("bgColor = $bgColor");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* fill-to-fit, ff - affecting the resulting image width, height and resize options
|
||||
*/
|
||||
$fillToFit = get(array('fill-to-fit', 'ff'), null);
|
||||
|
||||
verbose("fill-to-fit = $fillToFit");
|
||||
|
||||
if ($fillToFit !== null) {
|
||||
|
||||
if (!empty($fillToFit)) {
|
||||
$bgColor = $fillToFit;
|
||||
verbose("fillToFit changed bgColor to = $bgColor");
|
||||
}
|
||||
|
||||
$fillToFit = true;
|
||||
verbose("fill-to-fit (fixed) = $fillToFit");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* no-ratio, nr, stretch - affecting the resulting image width, height and resize options
|
||||
*/
|
||||
$keepRatio = getDefined(array('no-ratio', 'nr', 'stretch'), false, true);
|
||||
|
||||
verbose("keep ratio = $keepRatio");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* crop, c - affecting the resulting image width, height and resize options
|
||||
*/
|
||||
$crop = get(array('crop', 'c'));
|
||||
|
||||
verbose("crop = $crop");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* area, a - affecting the resulting image width, height and resize options
|
||||
*/
|
||||
$area = get(array('area', 'a'));
|
||||
|
||||
verbose("area = $area");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* skip-original, so - skip the original image and always process a new image
|
||||
*/
|
||||
$useOriginal = getDefined(array('skip-original', 'so'), false, true);
|
||||
|
||||
verbose("use original = $useOriginal");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* no-cache, nc - skip the cached version and process and create a new version in cache.
|
||||
*/
|
||||
$useCache = getDefined(array('no-cache', 'nc'), false, true);
|
||||
|
||||
verbose("use cache = $useCache");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* quality, q - set level of quality for jpeg images
|
||||
*/
|
||||
$quality = get(array('quality', 'q'));
|
||||
|
||||
is_null($quality)
|
||||
or ($quality > 0 and $quality <= 100)
|
||||
or errorPage('Quality out of range');
|
||||
|
||||
verbose("quality = $quality");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* compress, co - what strategy to use when compressing png images
|
||||
*/
|
||||
$compress = get(array('compress', 'co'));
|
||||
|
||||
|
||||
is_null($compress)
|
||||
or ($compress > 0 and $compress <= 9)
|
||||
or errorPage('Compress out of range');
|
||||
|
||||
verbose("compress = $compress");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* save-as, sa - what type of image to save
|
||||
*/
|
||||
$saveAs = get(array('save-as', 'sa'));
|
||||
|
||||
verbose("save as = $saveAs");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* scale, s - Processing option, scale up or down the image prior actual resize
|
||||
*/
|
||||
$scale = get(array('scale', 's'));
|
||||
|
||||
is_null($scale)
|
||||
or ($scale >= 0 and $scale <= 400)
|
||||
or errorPage('Scale out of range');
|
||||
|
||||
verbose("scale = $scale");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* palette, p - Processing option, create a palette version of the image
|
||||
*/
|
||||
$palette = getDefined(array('palette', 'p'), true, false);
|
||||
|
||||
verbose("palette = $palette");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* sharpen - Processing option, post filter for sharpen effect
|
||||
*/
|
||||
$sharpen = getDefined('sharpen', true, null);
|
||||
|
||||
verbose("sharpen = $sharpen");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* emboss - Processing option, post filter for emboss effect
|
||||
*/
|
||||
$emboss = getDefined('emboss', true, null);
|
||||
|
||||
verbose("emboss = $emboss");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* blur - Processing option, post filter for blur effect
|
||||
*/
|
||||
$blur = getDefined('blur', true, null);
|
||||
|
||||
verbose("blur = $blur");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* rotateBefore - Rotate the image with an angle, before processing
|
||||
*/
|
||||
$rotateBefore = get(array('rotateBefore', 'rotate-before', 'rb'));
|
||||
|
||||
is_null($rotateBefore)
|
||||
or ($rotateBefore >= -360 and $rotateBefore <= 360)
|
||||
or errorPage('RotateBefore out of range');
|
||||
|
||||
verbose("rotateBefore = $rotateBefore");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* rotateAfter - Rotate the image with an angle, before processing
|
||||
*/
|
||||
$rotateAfter = get(array('rotateAfter', 'rotate-after', 'ra', 'rotate', 'r'));
|
||||
|
||||
is_null($rotateAfter)
|
||||
or ($rotateAfter >= -360 and $rotateAfter <= 360)
|
||||
or errorPage('RotateBefore out of range');
|
||||
|
||||
verbose("rotateAfter = $rotateAfter");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* autoRotate - Auto rotate based on EXIF information
|
||||
*/
|
||||
$autoRotate = getDefined(array('autoRotate', 'auto-rotate', 'aro'), true, false);
|
||||
|
||||
verbose("autoRotate = $autoRotate");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* filter, f, f0-f9 - Processing option, post filter for various effects using imagefilter()
|
||||
*/
|
||||
$filters = array();
|
||||
$filter = get(array('filter', 'f'));
|
||||
if ($filter) {
|
||||
$filters[] = $filter;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < 10; $i++) {
|
||||
$filter = get(array("filter{$i}", "f{$i}"));
|
||||
if ($filter) {
|
||||
$filters[] = $filter;
|
||||
}
|
||||
}
|
||||
|
||||
verbose("filters = " . print_r($filters, 1));
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* json - output the image as a JSON object with details on the image.
|
||||
*/
|
||||
$outputFormat = getDefined('json', 'json', null);
|
||||
|
||||
verbose("json = $outputFormat");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* dpr - change to get larger image to easier support larger dpr, such as retina.
|
||||
*/
|
||||
$dpr = get(array('ppi', 'dpr', 'device-pixel-ratio'), 1);
|
||||
|
||||
verbose("dpr = $dpr");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* convolve - image convolution as in http://php.net/manual/en/function.imageconvolution.php
|
||||
*/
|
||||
$convolve = get('convolve', null);
|
||||
$convolutionConstant = getConfig('convolution_constant', array());
|
||||
|
||||
// Check if the convolve is matching an existing constant
|
||||
if ($convolve && isset($convolutionConstant)) {
|
||||
$img->addConvolveExpressions($convolutionConstant);
|
||||
verbose("convolve constant = " . print_r($convolutionConstant, 1));
|
||||
}
|
||||
|
||||
verbose("convolve = " . print_r($convolve, 1));
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* no-upscale, nu - Do not upscale smaller image to larger dimension.
|
||||
*/
|
||||
$upscale = getDefined(array('no-upscale', 'nu'), false, true);
|
||||
|
||||
verbose("upscale = $upscale");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get details for post processing
|
||||
*/
|
||||
$postProcessing = getConfig('postprocessing', array(
|
||||
'png_filter' => false,
|
||||
'png_filter_cmd' => '/usr/local/bin/optipng -q',
|
||||
|
||||
'png_deflate' => false,
|
||||
'png_deflate_cmd' => '/usr/local/bin/pngout -q',
|
||||
|
||||
'jpeg_optimize' => false,
|
||||
'jpeg_optimize_cmd' => '/usr/local/bin/jpegtran -copy none -optimize',
|
||||
));
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* alias - Save resulting image to another alias name.
|
||||
* Password always apply, must be defined.
|
||||
*/
|
||||
$alias = get('alias', null);
|
||||
$aliasPath = getConfig('alias_path', null);
|
||||
$validAliasname = getConfig('valid_aliasname', '#^[a-z0-9A-Z-_]+$#');
|
||||
$aliasTarget = null;
|
||||
|
||||
if ($alias && $aliasPath && $passwordMatch) {
|
||||
|
||||
$aliasTarget = $aliasPath . $alias;
|
||||
$useCache = false;
|
||||
|
||||
is_writable($aliasPath)
|
||||
or errorPage("Directory for alias is not writable.");
|
||||
|
||||
preg_match($validAliasname, $alias)
|
||||
or errorPage('Filename for alias contains invalid characters. Do not add extension.');
|
||||
|
||||
} else if ($alias) {
|
||||
errorPage('Alias is not enabled in the config file or password not matching.');
|
||||
}
|
||||
|
||||
verbose("alias = $alias");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Display image if verbose mode
|
||||
*/
|
||||
if ($verbose) {
|
||||
$query = array();
|
||||
parse_str($_SERVER['QUERY_STRING'], $query);
|
||||
unset($query['verbose']);
|
||||
unset($query['v']);
|
||||
unset($query['nocache']);
|
||||
unset($query['nc']);
|
||||
unset($query['json']);
|
||||
$url1 = '?' . htmlentities(urldecode(http_build_query($query)));
|
||||
$url2 = '?' . urldecode(http_build_query($query));
|
||||
echo <<<EOD
|
||||
<a href=$url1><code>$url1</code></a><br>
|
||||
<img src='{$url1}' />
|
||||
<pre id="json"></pre>
|
||||
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
window.getDetails = function (url, id) {
|
||||
$.getJSON(url, function(data) {
|
||||
element = document.getElementById(id);
|
||||
element.innerHTML = "filename: " + data.filename + "\\ncolors: " + data.colors + "\\nsize: " + data.size + "\\nwidth: " + data.width + "\\nheigh: " + data.height + "\\naspect-ratio: " + data.aspectRatio;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<script type="text/javascript">window.getDetails("{$url2}&json", "json")</script>
|
||||
EOD;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the cachepath from config.
|
||||
*/
|
||||
$cachePath = getConfig('cache_path', __DIR__ . '/../cache/');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Load, process and output the image
|
||||
*/
|
||||
$img->log("Incoming arguments: " . print_r(verbose(), 1))
|
||||
->setSaveFolder($cachePath)
|
||||
->useCache($useCache)
|
||||
->setSource($srcImage, $imagePath)
|
||||
->setOptions(
|
||||
array(
|
||||
// Options for calculate dimensions
|
||||
'newWidth' => $newWidth,
|
||||
'newHeight' => $newHeight,
|
||||
'aspectRatio' => $aspectRatio,
|
||||
'keepRatio' => $keepRatio,
|
||||
'cropToFit' => $cropToFit,
|
||||
'fillToFit' => $fillToFit,
|
||||
'crop' => $crop,
|
||||
'area' => $area,
|
||||
'upscale' => $upscale,
|
||||
|
||||
// Pre-processing, before resizing is done
|
||||
'scale' => $scale,
|
||||
'rotateBefore' => $rotateBefore,
|
||||
'autoRotate' => $autoRotate,
|
||||
|
||||
// General processing options
|
||||
'bgColor' => $bgColor,
|
||||
|
||||
// Post-processing, after resizing is done
|
||||
'palette' => $palette,
|
||||
'filters' => $filters,
|
||||
'sharpen' => $sharpen,
|
||||
'emboss' => $emboss,
|
||||
'blur' => $blur,
|
||||
'convolve' => $convolve,
|
||||
'rotateAfter' => $rotateAfter,
|
||||
|
||||
// Output format
|
||||
'outputFormat' => $outputFormat,
|
||||
'dpr' => $dpr,
|
||||
)
|
||||
)
|
||||
->loadImageDetails()
|
||||
->initDimensions()
|
||||
->calculateNewWidthAndHeight()
|
||||
->setSaveAsExtension($saveAs)
|
||||
->setJpegQuality($quality)
|
||||
->setPngCompression($compress)
|
||||
->useOriginalIfPossible($useOriginal)
|
||||
->generateFilename($cachePath)
|
||||
->useCacheIfPossible($useCache)
|
||||
->load()
|
||||
->preResize()
|
||||
->resize()
|
||||
->postResize()
|
||||
->setPostProcessingOptions($postProcessing)
|
||||
->save()
|
||||
->linkToCacheFile($aliasTarget)
|
||||
->output();
|
BIN
webroot/img/apple_trans.gif
Normal file
After Width: | Height: | Size: 8.3 KiB |
BIN
webroot/img/ball24.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
webroot/img/ball8.png
Normal file
After Width: | Height: | Size: 6.2 KiB |
BIN
webroot/img/car.gif
Normal file
After Width: | Height: | Size: 47 KiB |
BIN
webroot/img/car.jpg
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
webroot/img/car.png
Normal file
After Width: | Height: | Size: 245 KiB |
BIN
webroot/img/circle_trans.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
webroot/img/glider_anim.gif
Normal file
After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 165 KiB |
BIN
webroot/img/issue29/400x265.jpg
Normal file
After Width: | Height: | Size: 925 B |
BIN
webroot/img/issue29/400x268.jpg
Normal file
After Width: | Height: | Size: 925 B |
BIN
webroot/img/issue29/400x300.jpg
Normal file
After Width: | Height: | Size: 995 B |
BIN
webroot/img/issue29/465x304.jpg
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
webroot/img/issue29/640x273.jpg
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
webroot/img/issue34/3.jpg
Normal file
After Width: | Height: | Size: 50 KiB |
BIN
webroot/img/issue34/4.jpg
Normal file
After Width: | Height: | Size: 8.8 KiB |
BIN
webroot/img/issue36/flower-0.jpg
Normal file
After Width: | Height: | Size: 89 KiB |
BIN
webroot/img/issue36/flower-180.jpg
Normal file
After Width: | Height: | Size: 85 KiB |
BIN
webroot/img/issue36/flower-270.jpg
Normal file
After Width: | Height: | Size: 84 KiB |
BIN
webroot/img/issue36/flower-90.jpg
Normal file
After Width: | Height: | Size: 81 KiB |
BIN
webroot/img/issue36/me-0.jpg
Normal file
After Width: | Height: | Size: 76 KiB |
BIN
webroot/img/issue36/me-180.jpg
Normal file
After Width: | Height: | Size: 75 KiB |
BIN
webroot/img/issue36/me-270.jpg
Normal file
After Width: | Height: | Size: 72 KiB |
BIN
webroot/img/issue36/me-90.jpg
Normal file
After Width: | Height: | Size: 73 KiB |
BIN
webroot/img/issue40/source.jpg
Normal file
After Width: | Height: | Size: 404 KiB |
BIN
webroot/img/kodim04.png
Normal file
After Width: | Height: | Size: 622 KiB |
BIN
webroot/img/kodim07.png
Normal file
After Width: | Height: | Size: 544 KiB |
BIN
webroot/img/kodim08.png
Normal file
After Width: | Height: | Size: 770 KiB |
BIN
webroot/img/kodim13.png
Normal file
After Width: | Height: | Size: 803 KiB |
BIN
webroot/img/kodim15.png
Normal file
After Width: | Height: | Size: 589 KiB |
BIN
webroot/img/kodim22.png
Normal file
After Width: | Height: | Size: 684 KiB |
BIN
webroot/img/kodim23.png
Normal file
After Width: | Height: | Size: 544 KiB |
BIN
webroot/img/kodim24.png
Normal file
After Width: | Height: | Size: 681 KiB |
BIN
webroot/img/round24.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
webroot/img/round8.PNG
Normal file
After Width: | Height: | Size: 6.2 KiB |
BIN
webroot/img/round8.png
Normal file
After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
BIN
webroot/img/wider.JPG
Normal file
After Width: | Height: | Size: 70 KiB |
BIN
webroot/img/wider.jpg
Normal file
After Width: | Height: | Size: 70 KiB |
277
webroot/img_config.php
Normal file
@@ -0,0 +1,277 @@
|
||||
<?php
|
||||
/**
|
||||
* Configuration for img.php, name the config file the same as your img.php and
|
||||
* append _config. If you are testing out some in imgtest.php then label that
|
||||
* config-file imgtest_config.php.
|
||||
*
|
||||
*/
|
||||
return array(
|
||||
|
||||
/**
|
||||
* Set mode as 'strict', 'production' or 'development'.
|
||||
*
|
||||
* Default values:
|
||||
* mode: 'production'
|
||||
*/
|
||||
'mode' => 'development',
|
||||
//'mode' => 'production', // 'development', 'strict'
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Where are the sources for the classfiles.
|
||||
*
|
||||
* Default values:
|
||||
* autoloader: null // used from v0.6.2
|
||||
* cimage_class: null // used until v0.6.1
|
||||
*/
|
||||
'autoloader' => __DIR__ . '/../autoload.php',
|
||||
//'cimage_class' => __DIR__ . '/../CImage.php',
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Paths, where are the images stored and where is the cache.
|
||||
* End all paths with a slash.
|
||||
*
|
||||
* Default values:
|
||||
* image_path: __DIR__ . '/img/'
|
||||
* cache_path: __DIR__ . '/../cache/'
|
||||
* alias_path: null
|
||||
*/
|
||||
'image_path' => __DIR__ . '/img/',
|
||||
'cache_path' => __DIR__ . '/../cache/',
|
||||
//'alias_path' => __DIR__ . '/img/alias/',
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Use password to protect from missusage, send &pwd=... or &password=..
|
||||
* with the request to match the password or set to false to disable.
|
||||
* Passwords are only used together with the options for remote download
|
||||
* and aliasing.
|
||||
*
|
||||
* Default values.
|
||||
* password: false // as in do not use password
|
||||
* password_always: false // do not always require password,
|
||||
*/
|
||||
//'password' => false, // "secret-password",
|
||||
//'password_always' => false, // always require password,
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Allow or disallow downloading of remote files, images available on
|
||||
* some remote server. Default is to disallow.
|
||||
*
|
||||
* Default values.
|
||||
* remote_allow: false
|
||||
* remote_pattern: null // use default values from CImage
|
||||
*/
|
||||
//'remote_allow' => true,
|
||||
//'remote_pattern' => '#^https?://#',
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A regexp for validating characters in the image or alias filename.
|
||||
*
|
||||
* Default value:
|
||||
* valid_filename: '#^[a-z0-9A-Z-/_\.:]+$#'
|
||||
* valid_aliasname: '#^[a-z0-9A-Z-_]+$#'
|
||||
*/
|
||||
//'valid_filename' => '#^[a-z0-9A-Z-/_\.:]+$#',
|
||||
//'valid_aliasname' => '#^[a-z0-9A-Z-_]+$#',
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Check that the imagefile is a file below 'image_path' using realpath().
|
||||
* Security constraint to avoid reaching images outside image_path.
|
||||
* This means that symbolic links to images outside the image_path will fail.
|
||||
*
|
||||
* Default value:
|
||||
* image_path_constraint: true
|
||||
*/
|
||||
//'image_path_constraint' => false,
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set default timezone.
|
||||
*
|
||||
* Default values.
|
||||
* default_timezone: ini_get('default_timezone') or 'UTC'
|
||||
*/
|
||||
//'default_timezone' => 'UTC',
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Max image dimensions, larger dimensions results in 404.
|
||||
* This is basically a security constraint to avoid using resources on creating
|
||||
* large (unwanted) images.
|
||||
*
|
||||
* Default values.
|
||||
* max_width: 2000
|
||||
* max_height: 2000
|
||||
*/
|
||||
//'max_width' => 2000,
|
||||
//'max_height' => 2000,
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set default background color for all images. Override it using
|
||||
* option bgColor.
|
||||
* Colorvalue is 6 digit hex string between 000000-FFFFFF
|
||||
* or 8 digit hex string if using the alpha channel where
|
||||
* the alpha value is between 00 (opaqe) and 7F (transparent),
|
||||
* that is between 00000000-FFFFFF7F.
|
||||
*
|
||||
* Default values.
|
||||
* background_color: As specified by CImage
|
||||
*/
|
||||
//'background_color' => "FFFFFF",
|
||||
//'background_color' => "FFFFFF7F",
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Post processing of images using external tools, set to true or false
|
||||
* and set command to be executed.
|
||||
*
|
||||
* Default values.
|
||||
*
|
||||
* png_filter: false
|
||||
* png_filter_cmd: '/usr/local/bin/optipng -q'
|
||||
*
|
||||
* png_deflate: false
|
||||
* png_deflate_cmd: '/usr/local/bin/pngout -q'
|
||||
*
|
||||
* jpeg_optimize: false
|
||||
* jpeg_optimize_cmd: '/usr/local/bin/jpegtran -copy none -optimize'
|
||||
*/
|
||||
/*
|
||||
'postprocessing' => array(
|
||||
'png_filter' => false,
|
||||
'png_filter_cmd' => '/usr/local/bin/optipng -q',
|
||||
|
||||
'png_deflate' => false,
|
||||
'png_deflate_cmd' => '/usr/local/bin/pngout -q',
|
||||
|
||||
'jpeg_optimize' => false,
|
||||
'jpeg_optimize_cmd' => '/usr/local/bin/jpegtran -copy none -optimize',
|
||||
),
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create custom convolution expressions, matrix 3x3, divisor and
|
||||
* offset.
|
||||
*
|
||||
* Default values.
|
||||
* convolution_constant: array()
|
||||
*/
|
||||
/*
|
||||
'convolution_constant' => array(
|
||||
//'sharpen' => '-1,-1,-1, -1,16,-1, -1,-1,-1, 8, 0',
|
||||
//'sharpen-alt' => '0,-1,0, -1,5,-1, 0,-1,0, 1, 0',
|
||||
),
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Prevent leeching of images by controlling who can access them from where.
|
||||
* Default it to allow hotlinking.
|
||||
* Password apply when hotlinking is disallowed, use password to allow.
|
||||
* The whitelist is an array of regexpes for allowed hostnames that can
|
||||
* hotlink images.
|
||||
*
|
||||
* Default values.
|
||||
* allow_hotlinking: true
|
||||
* hotlinking_whitelist: array()
|
||||
*/
|
||||
/*
|
||||
'allow_hotlinking' => false,
|
||||
'hotlinking_whitelist' => array(
|
||||
'#^localhost$#',
|
||||
'#^dbwebb\.se$#',
|
||||
),
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create custom shortcuts for more advanced expressions.
|
||||
*
|
||||
* Default values.
|
||||
* shortcut: array(
|
||||
* 'sepia' => "&f=grayscale&f0=brightness,-10&f1=contrast,-20&f2=colorize,120,60,0,0&sharpen",
|
||||
* )
|
||||
*/
|
||||
/*
|
||||
'shortcut' => array(
|
||||
'sepia' => "&f=grayscale&f0=brightness,-10&f1=contrast,-20&f2=colorize,120,60,0,0&sharpen",
|
||||
),*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Predefined size constants.
|
||||
*
|
||||
* These can be used together with &width or &height to create a constant value
|
||||
* for a width or height where can be changed in one place.
|
||||
* Useful when your site changes its layout or if you have a grid to fit images into.
|
||||
*
|
||||
* Example:
|
||||
* &width=w1 // results in width=613
|
||||
* &width=c2 // results in spanning two columns with a gutter, 30*2+10=70
|
||||
* &width=c24 // results in spanning whole grid 24*30+((24-1)*10)=950
|
||||
*
|
||||
* Default values.
|
||||
* size_constant: As specified by the function below.
|
||||
*/
|
||||
/*
|
||||
'size_constant' => function () {
|
||||
|
||||
// Set sizes to map constant to value, easier to use with width or height
|
||||
$sizes = array(
|
||||
'w1' => 613,
|
||||
'w2' => 630,
|
||||
);
|
||||
|
||||
// Add grid column width, useful for use as predefined size for width (or height).
|
||||
$gridColumnWidth = 30;
|
||||
$gridGutterWidth = 10;
|
||||
$gridColumns = 24;
|
||||
|
||||
for ($i = 1; $i <= $gridColumns; $i++) {
|
||||
$sizes['c' . $i] = ($gridColumnWidth + $gridGutterWidth) * $i - $gridGutterWidth;
|
||||
}
|
||||
|
||||
return $sizes;
|
||||
},*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Predefined aspect ratios.
|
||||
*
|
||||
* Default values.
|
||||
* aspect_ratio_constant: As the function below.
|
||||
*/
|
||||
/*'aspect_ratio_constant' => function () {
|
||||
return array(
|
||||
'3:1' => 3/1,
|
||||
'3:2' => 3/2,
|
||||
'4:3' => 4/3,
|
||||
'8:5' => 8/5,
|
||||
'16:10' => 16/10,
|
||||
'16:9' => 16/9,
|
||||
'golden' => 1.618,
|
||||
);
|
||||
},*/
|
||||
);
|
35
webroot/img_header.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* Resize and crop images on the fly, store generated images in a cache.
|
||||
*
|
||||
* This version is a all-in-one version of img.php, it is not dependant an any other file
|
||||
* so you can simply copy it to any place you want it.
|
||||
*
|
||||
* @author Mikael Roos mos@dbwebb.se
|
||||
* @example http://dbwebb.se/opensource/cimage
|
||||
* @link https://github.com/mosbth/cimage
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Change configuration details in the array below or create a separate file
|
||||
* where you store the configuration details.
|
||||
*
|
||||
* The configuration file should be named the same name as this file and then
|
||||
* add '_config.php'. If this file is named 'img.php' then name the
|
||||
* config file should be named 'img_config.php'.
|
||||
*
|
||||
* The settings below are only a few of the available ones. Check the file in
|
||||
* webroot/img_config.php for a complete list of configuration options.
|
||||
*/
|
||||
$config = array(
|
||||
|
||||
//'mode' => 'production', // 'production', 'development', 'strict'
|
||||
//'image_path' => __DIR__ . '/img/',
|
||||
//'cache_path' => __DIR__ . '/../cache/',
|
||||
//'alias_path' => __DIR__ . '/img/alias/',
|
||||
//'remote_allow' => true,
|
||||
//'password' => false, // "secret-password",
|
||||
|
||||
);
|
3906
webroot/imgd.php
Normal file
3906
webroot/imgp.php
Normal file
3906
webroot/imgs.php
Normal file
163
webroot/js/cimage.js
Normal file
@@ -0,0 +1,163 @@
|
||||
/**
|
||||
* JavaScript utilities for CImage and img.php.
|
||||
*/
|
||||
window.CImage = (function(){
|
||||
"use strict";
|
||||
|
||||
|
||||
/**
|
||||
* Init the compare page with details.
|
||||
*/
|
||||
function compareLoadImage(event) {
|
||||
var img, json, button, area, deck, id;
|
||||
|
||||
id = this.dataset.id;
|
||||
img = document.getElementById("img" + id);
|
||||
json = document.getElementById("json" + id);
|
||||
button = document.getElementById("button" + id);
|
||||
area = document.getElementById("area" + id);
|
||||
deck = document.getElementById("deck" + id);
|
||||
|
||||
if (this.value == "") {
|
||||
// Clear image if input is cleared
|
||||
button.setAttribute("disabled", "disabled");
|
||||
area.classList.add("hidden");
|
||||
button.classList.remove("selected");
|
||||
return;
|
||||
}
|
||||
|
||||
// Display image in its area
|
||||
img.src = this.value;
|
||||
area.classList.remove("hidden");
|
||||
|
||||
$.getJSON(this.value + "&json", function(data) {
|
||||
json.innerHTML = "filename: " + data.filename + "\ncolors: " + data.colors + "\nsize: " + data.size + "\nwidth: " + data.width + "\nheigh: " + data.height + "\naspect-ratio: " + data.aspectRatio;
|
||||
});
|
||||
|
||||
// Display image in overlay
|
||||
button.removeAttribute("disabled");
|
||||
button.classList.add("selected");
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Init the compare page with details.
|
||||
*/
|
||||
function compareInit(options)
|
||||
{
|
||||
var elements, id, onTop, myEvent,
|
||||
input1 = document.getElementById("input1"),
|
||||
input2 = document.getElementById("input2"),
|
||||
input3 = document.getElementById("input3"),
|
||||
input4 = document.getElementById("input4"),
|
||||
details = document.getElementById("viewDetails"),
|
||||
stack = document.getElementById("stack"),
|
||||
buttons = document.getElementById("buttonWrap");
|
||||
|
||||
/* img1 = document.getElementById("img1"),
|
||||
img2 = document.getElementById("img2"),
|
||||
img3 = document.getElementById("img3"),
|
||||
img4 = document.getElementById("img4"),
|
||||
img01 = document.getElementById("img01"),
|
||||
img02 = document.getElementById("img02"),
|
||||
img03 = document.getElementById("img03"),
|
||||
img04 = document.getElementById("img04"),
|
||||
json1 = document.getElementById("json1"),
|
||||
json2 = document.getElementById("json2"),
|
||||
json3 = document.getElementById("json3"),
|
||||
json4 = document.getElementById("json4"),
|
||||
json01 = document.getElementById("json01"),
|
||||
json02 = document.getElementById("json02"),
|
||||
json03 = document.getElementById("json03"),
|
||||
json04 = document.getElementById("json04"),
|
||||
button1 = document.getElementById("button1"),
|
||||
button2 = document.getElementById("button2"),
|
||||
button3 = document.getElementById("button3"),
|
||||
button4 = document.getElementById("button4"),
|
||||
area1 = document.getElementById("area1"),
|
||||
area2 = document.getElementById("area2"),
|
||||
area3 = document.getElementById("area3"),
|
||||
area4 = document.getElementById("area4");*/
|
||||
|
||||
input1.addEventListener("change", compareLoadImage);
|
||||
input2.addEventListener("change", compareLoadImage);
|
||||
input3.addEventListener("change", compareLoadImage);
|
||||
input4.addEventListener("change", compareLoadImage);
|
||||
|
||||
// Toggle json
|
||||
details.addEventListener("change", function() {
|
||||
var elements = document.querySelectorAll(".json");
|
||||
for (var element of elements) {
|
||||
element.classList.toggle("hidden");
|
||||
}
|
||||
});
|
||||
|
||||
// Do not show json as default
|
||||
if (options.json === false) {
|
||||
details.setAttribute("checked", "checked");
|
||||
myEvent = new CustomEvent("change");
|
||||
details.dispatchEvent(myEvent);
|
||||
}
|
||||
|
||||
// Toggle stack
|
||||
stack.addEventListener("change", function() {
|
||||
var element,
|
||||
elements = document.querySelectorAll(".area");
|
||||
|
||||
buttons.classList.toggle("hidden");
|
||||
|
||||
for (element of elements) {
|
||||
element.classList.toggle("stack");
|
||||
|
||||
if (!element.classList.contains('hidden')) {
|
||||
onTop = element;
|
||||
}
|
||||
}
|
||||
onTop.classList.toggle("top");
|
||||
|
||||
console.log("Stacking");
|
||||
});
|
||||
|
||||
// Stack as default
|
||||
if (options.stack === true) {
|
||||
stack.setAttribute("checked", "checked");
|
||||
myEvent = new CustomEvent("change");
|
||||
stack.dispatchEvent(myEvent);
|
||||
}
|
||||
|
||||
// Button clicks
|
||||
elements = document.querySelectorAll(".button");
|
||||
for (var element of elements) {
|
||||
element.addEventListener("click", function() {
|
||||
var id = this.dataset.id,
|
||||
area = document.getElementById("area" + id);
|
||||
|
||||
area.classList.toggle("top");
|
||||
onTop.classList.toggle("top");
|
||||
onTop = area;
|
||||
console.log("button" + id);
|
||||
});
|
||||
}
|
||||
|
||||
input1.value = options.input1 || null;
|
||||
input2.value = options.input2 || null;
|
||||
input3.value = options.input3 || null;
|
||||
input4.value = options.input4 || null;
|
||||
|
||||
compareLoadImage.call(input1);
|
||||
compareLoadImage.call(input2);
|
||||
compareLoadImage.call(input3);
|
||||
compareLoadImage.call(input4);
|
||||
|
||||
console.log(options);
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
"compare": compareInit
|
||||
};
|
||||
|
||||
}());
|
8
webroot/test/config.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
// Use error reporting
|
||||
error_reporting(-1);
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
|
||||
// The link to img.php
|
||||
$imgphp = "../img.php?src=";
|
101
webroot/test/template.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<!doctype html>
|
||||
<head>
|
||||
<meta charset='utf-8'/>
|
||||
<title><?=$title?></title>
|
||||
<style>
|
||||
body {background-color: #ccc;}
|
||||
</style>
|
||||
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
window.getDetails = function (url, id) {
|
||||
$.getJSON(url, function(data) {
|
||||
element = document.getElementById(id);
|
||||
element.innerHTML = "filename: " + data.filename + "\ncolors: " + data.colors + "\nsize: " + data.size + "\nwidth: " + data.width + "\nheigh: " + data.height + "\naspect-ratio: " + data.aspectRatio;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<h1><?=$title?></h1>
|
||||
|
||||
<?php if (isset($description)) : ?>
|
||||
<p><?=$description?></p>
|
||||
<?php endif; ?>
|
||||
|
||||
<h2>Images used in test</h2>
|
||||
|
||||
<p>The following images are used for this test.</p>
|
||||
|
||||
<?php foreach($images as $image) : ?>
|
||||
<p>
|
||||
<code>
|
||||
<a href="img/<?=$image?>"><?=$image?></a>
|
||||
<a href="<?=$imgphp . $image . '&json'?>">(json)</a>
|
||||
<a href="<?=$imgphp . $image . '&verbose'?>">(verbose)</a>
|
||||
</code>
|
||||
<br>
|
||||
<img src="<?=$imgphp . $image?>"></p>
|
||||
<p></p>
|
||||
|
||||
<pre id="<?=$image?>"></pre>
|
||||
<script type="text/javascript">window.getDetails("<?=$imgphp . $image . '&json'?>", "<?=$image?>")</script>
|
||||
|
||||
<?php endforeach; ?>
|
||||
|
||||
|
||||
|
||||
<h2>Testcases used for each image</h2>
|
||||
|
||||
<p>The following testcases are used for each image.</p>
|
||||
|
||||
<?php foreach($testcase as $tc) : ?>
|
||||
<code><?=$tc?></code><br>
|
||||
<?php endforeach; ?>
|
||||
|
||||
|
||||
|
||||
<h2>For each image, apply all testcases</h2>
|
||||
|
||||
<?php
|
||||
$ch1 = 1;
|
||||
foreach($images as $image) :
|
||||
?>
|
||||
<h3><?=$ch1?>. Using source image <?=$image?></h3>
|
||||
|
||||
<p>
|
||||
<code>
|
||||
<a href="img/<?=$image?>"><?=$image?></a>
|
||||
<a href="<?=$imgphp . $image . '&json'?>">(json)</a>
|
||||
<a href="<?=$imgphp . $image . '&verbose'?>">(verbose)</a>
|
||||
</code>
|
||||
<br>
|
||||
<img src="<?=$imgphp . $image?>">
|
||||
</p>
|
||||
|
||||
<pre id="<?=$ch1?>"></pre>
|
||||
<script type="text/javascript">window.getDetails("<?=$imgphp . $image . '&json'?>", "<?=$ch1?>")</script>
|
||||
|
||||
<?php
|
||||
$ch2 = 1;
|
||||
foreach($testcase as $tc) :
|
||||
$tcId = "$ch1.$ch2";
|
||||
?>
|
||||
<h4>Testcase <?=$tcId?>: <?=$tc?></h4>
|
||||
|
||||
<p>
|
||||
<code>
|
||||
<a href="<?=$imgphp . $image . $tc?>"><?=$image . $tc?></a>
|
||||
<a href="<?=$imgphp . $image . $tc . '&json'?>">(json)</a>
|
||||
<a href="<?=$imgphp . $image . $tc . '&verbose'?>">(verbose)</a>
|
||||
</code>
|
||||
<br>
|
||||
<img src="<?=$imgphp . $image . $tc?>">
|
||||
</p>
|
||||
|
||||
<pre id="<?=$tcId?>"></pre>
|
||||
<script type="text/javascript">window.getDetails("<?=$imgphp . $image . $tc . '&json'?>", "<?=$tcId?>")</script>
|
||||
|
||||
<?php $ch2++; endforeach; ?>
|
||||
<?php $ch1++; endforeach; ?>
|
73
webroot/test/test.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<!doctype html>
|
||||
<head>
|
||||
<meta charset='utf-8'/>
|
||||
<title>Testing img resizing using CImage.php</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Testing <code>CImage.php</code> through <code>img.php</code></h1>
|
||||
|
||||
<h2>Testcases</h2>
|
||||
|
||||
<?php
|
||||
$testcase = array(
|
||||
array('text'=>'Original image', 'query'=>''),
|
||||
array('text'=>'Crop out a rectangle of 100x100, start by position 200x200.', 'query'=>'&crop=100,100,200,200'),
|
||||
array('text'=>'Crop out a full width rectangle with height of 200, start by position 0x100.', 'query'=>'&crop=0,200,0,100'),
|
||||
array('text'=>'Max width 200.', 'query'=>'&w=200'),
|
||||
array('text'=>'Max height 200.', 'query'=>'&h=200'),
|
||||
array('text'=>'Max width 200 and max height 200.', 'query'=>'&w=200&h=200'),
|
||||
array('text'=>'No-ratio makes image fit in area of width 200 and height 200.', 'query'=>'&w=200&h=200&no-ratio'),
|
||||
array('text'=>'Crop to fit in width 200 and height 200.', 'query'=>'&w=200&h=200&crop-to-fit'),
|
||||
array('text'=>'Crop to fit in width 200 and height 100.', 'query'=>'&w=200&h=100&crop-to-fit'),
|
||||
array('text'=>'Crop to fit in width 100 and height 200.', 'query'=>'&w=100&h=200&crop-to-fit'),
|
||||
array('text'=>'Quality 70', 'query'=>'&w=200&h=200&quality=70'),
|
||||
array('text'=>'Quality 40', 'query'=>'&w=200&h=200&quality=40'),
|
||||
array('text'=>'Quality 10', 'query'=>'&w=200&h=200&quality=10'),
|
||||
array('text'=>'Filter: Negate', 'query'=>'&w=200&h=200&f=negate'),
|
||||
array('text'=>'Filter: Grayscale', 'query'=>'&w=200&h=200&f=grayscale'),
|
||||
array('text'=>'Filter: Brightness 90', 'query'=>'&w=200&h=200&f=brightness,90'),
|
||||
array('text'=>'Filter: Contrast 50', 'query'=>'&w=200&h=200&f=contrast,50'),
|
||||
array('text'=>'Filter: Colorize 0,255,0,0', 'query'=>'&w=200&h=200&f=colorize,0,255,0,0'),
|
||||
array('text'=>'Filter: Edge detect', 'query'=>'&w=200&h=200&f=edgedetect'),
|
||||
array('text'=>'Filter: Emboss', 'query'=>'&w=200&h=200&f=emboss'),
|
||||
array('text'=>'Filter: Gaussian blur', 'query'=>'&w=200&h=200&f=gaussian_blur'),
|
||||
array('text'=>'Filter: Selective blur', 'query'=>'&w=200&h=200&f=selective_blur'),
|
||||
array('text'=>'Filter: Mean removal', 'query'=>'&w=200&h=200&f=mean_removal'),
|
||||
array('text'=>'Filter: Smooth 2', 'query'=>'&w=200&h=200&f=smooth,2'),
|
||||
array('text'=>'Filter: Pixelate 10,10', 'query'=>'&w=200&h=200&f=pixelate,10,10'),
|
||||
array('text'=>'Multiple filter: Negate, Grayscale and Pixelate 10,10', 'query'=>'&w=200&h=200&&f=negate&f0=grayscale&f1=pixelate,10,10'),
|
||||
array('text'=>'Crop with width & height and crop-to-fit with quality and filter', 'query'=>'&crop=100,100,100,100&w=200&h=200&crop-to-fit&q=70&f0=grayscale'),
|
||||
);
|
||||
?>
|
||||
|
||||
<h3>Test case with image <code>wider.jpg</code></h3>
|
||||
<table>
|
||||
<caption>Test case with image <code>wider.jpg</code></caption>
|
||||
<thead><tr><th>Testcase:</th><th>Result:</th></tr></thead>
|
||||
<tbody>
|
||||
<?php
|
||||
foreach($testcase as $key => $val) {
|
||||
$url = "../img.php?src=wider.jpg{$val['query']}";
|
||||
echo "<tr><td id=w$key><a href=#w$key>$key</a></br>{$val['text']}</br><code><a href='$url'>".htmlentities($url)."</a></code></td><td><img src='$url' /></td></tr>";
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h3>Test case with image <code>higher.jpg</code></h3>
|
||||
<table>
|
||||
<caption>Test case with image <code>higher.jpg</code></caption>
|
||||
<thead><tr><th>Testcase:</th><th>Result:</th></tr></thead>
|
||||
<tbody>
|
||||
<?php
|
||||
foreach($testcase as $key => $val) {
|
||||
$url = "../img.php?src=higher.jpg{$val['query']}";
|
||||
echo "<tr><td id=h$key><a href=#h$key>$key</a></br>{$val['text']}</br><code><a href='$url'>".htmlentities($url)."</a></code></td><td><img src='$url' /></td></tr>";
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
38
webroot/test/test_issue29.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
// Include config for all testcases
|
||||
include __DIR__ . "/config.php";
|
||||
|
||||
|
||||
|
||||
// The title of the test case
|
||||
$title = "Testing img for issue 29";
|
||||
|
||||
|
||||
|
||||
// Provide a short description of the testcase.
|
||||
$description = "";
|
||||
|
||||
|
||||
|
||||
// Use these images in the test
|
||||
$images = array(
|
||||
'issue29/400x265.jpg',
|
||||
'issue29/400x268.jpg',
|
||||
'issue29/400x300.jpg',
|
||||
'issue29/465x304.jpg',
|
||||
'issue29/640x273.jpg',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// For each image, apply these testcases
|
||||
$testcase = array(
|
||||
'&w=300&cf&q=80&nc',
|
||||
'&w=75&h=75&cf&q=80&nc',
|
||||
'&w=75&h=75&q=80',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Applu testcases and present results
|
||||
include __DIR__ . "/template.php";
|
42
webroot/test/test_issue36_aro.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
// Include config for all testcases
|
||||
include __DIR__ . "/config.php";
|
||||
|
||||
|
||||
|
||||
// The title of the test case
|
||||
$title = "Testing issue 36 - autoRotate";
|
||||
|
||||
|
||||
|
||||
// Provide a short description of the testcase.
|
||||
$description = "";
|
||||
|
||||
|
||||
|
||||
// Use these images in the test
|
||||
$images = array(
|
||||
'issue36/me-0.jpg',
|
||||
'issue36/me-90.jpg',
|
||||
'issue36/me-180.jpg',
|
||||
'issue36/me-270.jpg',
|
||||
'issue36/flower-0.jpg',
|
||||
'issue36/flower-90.jpg',
|
||||
'issue36/flower-180.jpg',
|
||||
'issue36/flower-270.jpg',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// For each image, apply these testcases
|
||||
$testcase = array(
|
||||
'&aro&nc',
|
||||
'&aro&nc&w=200',
|
||||
'&aro&nc&h=200',
|
||||
'&aro&nc&w=200&h=200&cf',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Applu testcases and present results
|
||||
include __DIR__ . "/template.php";
|
42
webroot/test/test_issue36_rb-ra-180.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
// Include config for all testcases
|
||||
include __DIR__ . "/config.php";
|
||||
|
||||
|
||||
|
||||
// The title of the test case
|
||||
$angle = 180;
|
||||
|
||||
$title = "Testing img for issue 36 - rotateBefore, rotateAfter <?=$angle?>";
|
||||
|
||||
|
||||
|
||||
// Provide a short description of the testcase.
|
||||
$description = "";
|
||||
|
||||
|
||||
|
||||
// Use these images in the test
|
||||
$images = array(
|
||||
'kodim08.png',
|
||||
'kodim04.png',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// For each image, apply these testcases
|
||||
$testcase = array(
|
||||
"&rb=$angle&nc",
|
||||
"&rb=$angle&nc&w=200",
|
||||
"&rb=$angle&nc&h=200",
|
||||
"&rb=$angle&nc&w=200&h=200&cf",
|
||||
"&ra=$angle&nc",
|
||||
"&ra=$angle&nc&w=200",
|
||||
"&ra=$angle&nc&h=200",
|
||||
"&ra=$angle&nc&w=200&h=200&cf",
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Apply testcases and present results
|
||||
include __DIR__ . "/template.php";
|
42
webroot/test/test_issue36_rb-ra-270.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
// Include config for all testcases
|
||||
include __DIR__ . "/config.php";
|
||||
|
||||
|
||||
|
||||
// The title of the test case
|
||||
$angle = 270;
|
||||
|
||||
$title = "Testing img for issue 36 - rotateBefore, rotateAfter <?=$angle?>";
|
||||
|
||||
|
||||
|
||||
// Provide a short description of the testcase.
|
||||
$description = "";
|
||||
|
||||
|
||||
|
||||
// Use these images in the test
|
||||
$images = array(
|
||||
'kodim08.png',
|
||||
'kodim04.png',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// For each image, apply these testcases
|
||||
$testcase = array(
|
||||
"&rb=$angle&nc",
|
||||
"&rb=$angle&nc&w=200",
|
||||
"&rb=$angle&nc&h=200",
|
||||
"&rb=$angle&nc&w=200&h=200&cf",
|
||||
"&ra=$angle&nc",
|
||||
"&ra=$angle&nc&w=200",
|
||||
"&ra=$angle&nc&h=200",
|
||||
"&ra=$angle&nc&w=200&h=200&cf",
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Apply testcases and present results
|
||||
include __DIR__ . "/template.php";
|
42
webroot/test/test_issue36_rb-ra-45.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
// Include config for all testcases
|
||||
include __DIR__ . "/config.php";
|
||||
|
||||
|
||||
|
||||
// The title of the test case
|
||||
$angle = 45;
|
||||
|
||||
$title = "Testing img for issue 36 - rotateBefore, rotateAfter <?=$angle?>";
|
||||
|
||||
|
||||
|
||||
// Provide a short description of the testcase.
|
||||
$description = "";
|
||||
|
||||
|
||||
|
||||
// Use these images in the test
|
||||
$images = array(
|
||||
'kodim08.png',
|
||||
'kodim04.png',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// For each image, apply these testcases
|
||||
$testcase = array(
|
||||
"&rb=$angle&nc",
|
||||
"&rb=$angle&nc&w=200",
|
||||
"&rb=$angle&nc&h=200",
|
||||
"&rb=$angle&nc&w=200&h=200&cf",
|
||||
"&ra=$angle&nc",
|
||||
"&ra=$angle&nc&w=200",
|
||||
"&ra=$angle&nc&h=200",
|
||||
"&ra=$angle&nc&w=200&h=200&cf",
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Apply testcases and present results
|
||||
include __DIR__ . "/template.php";
|
42
webroot/test/test_issue36_rb-ra-90.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
// Include config for all testcases
|
||||
include __DIR__ . "/config.php";
|
||||
|
||||
|
||||
|
||||
// The title of the test case
|
||||
$angle = 90;
|
||||
|
||||
$title = "Testing img for issue 36 - rotateBefore, rotateAfter <?=$angle?>";
|
||||
|
||||
|
||||
|
||||
// Provide a short description of the testcase.
|
||||
$description = "";
|
||||
|
||||
|
||||
|
||||
// Use these images in the test
|
||||
$images = array(
|
||||
'kodim08.png',
|
||||
'kodim04.png',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// For each image, apply these testcases
|
||||
$testcase = array(
|
||||
"&rb=$angle&nc",
|
||||
"&rb=$angle&nc&w=200",
|
||||
"&rb=$angle&nc&h=200",
|
||||
"&rb=$angle&nc&w=200&h=200&cf",
|
||||
"&ra=$angle&nc",
|
||||
"&ra=$angle&nc&w=200",
|
||||
"&ra=$angle&nc&h=200",
|
||||
"&ra=$angle&nc&w=200&h=200&cf",
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Applu testcases and present results
|
||||
include __DIR__ . "/template.php";
|
45
webroot/test/test_issue38.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
// Include config for all testcases
|
||||
include __DIR__ . "/config.php";
|
||||
|
||||
|
||||
|
||||
// The title of the test case
|
||||
$title = "Testing issue 38 - fill to fit, together with background colors";
|
||||
|
||||
|
||||
|
||||
// Provide a short description of the testcase.
|
||||
$description = "The issue was to implement fill-to-fit, but it needs some flexibility in how to choose the background color and it also affects rotation of the image (the background color does). So this testcase is both for fill-to-fit and for background color (thereby including a test using rotate).";
|
||||
|
||||
|
||||
|
||||
// Use these images in the test
|
||||
$images = array(
|
||||
'kodim04.png',
|
||||
'apple_trans.gif',
|
||||
'circle_trans.png',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// For each image, apply these testcases
|
||||
$cache = "&nc"; // ""; // "&nc"
|
||||
$testcase = array(
|
||||
"$cache&w=300&h=300&fill-to-fit",
|
||||
"$cache&w=200&h=400&fill-to-fit",
|
||||
"$cache&w=300&h=300&fill-to-fit=ff0000",
|
||||
"$cache&w=200&h=400&fill-to-fit=ff0000",
|
||||
"$cache&w=300&h=300&fill-to-fit=ff00003f",
|
||||
"$cache&w=200&h=400&fill-to-fit=ff00003f",
|
||||
"$cache&w=200&h=400&fill-to-fit&bgc=ff0000",
|
||||
"$cache&w=300&h=300&fill-to-fit&bgc=ff00003f",
|
||||
"$cache&w=300&h=300&ra=45",
|
||||
"$cache&w=300&h=300&ra=45&bgc=ff0000",
|
||||
"$cache&w=300&h=300&ra=45&bgc=ff00003f",
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Applu testcases and present results
|
||||
include __DIR__ . "/template.php";
|
37
webroot/test/test_issue40.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
// Include config for all testcases
|
||||
include __DIR__ . "/config.php";
|
||||
|
||||
|
||||
|
||||
// The title of the test case
|
||||
$title = "Testing issue 40 - no ratio";
|
||||
|
||||
|
||||
|
||||
// Provide a short description of the testcase.
|
||||
$description = "Showing off how to resize image with and without ratio.";
|
||||
|
||||
|
||||
|
||||
// Use these images in the test
|
||||
$images = array(
|
||||
'issue40/source.jpg',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// For each image, apply these testcases
|
||||
$testcase = array(
|
||||
'&nc&width=652&height=466',
|
||||
'&nc&width=652&height=466&no-ratio',
|
||||
'&nc&width=652&height=466&crop-to-fit',
|
||||
'&nc&width=652&aspect-ratio=1.4',
|
||||
'&nc&width=652&aspect-ratio=1.4&no-ratio',
|
||||
'&nc&width=652&aspect-ratio=1.4&crop-to-fit',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Apply testcases and present results
|
||||
include __DIR__ . "/template.php";
|
38
webroot/test/test_issue49.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
// Include config for all testcases
|
||||
include __DIR__ . "/config.php";
|
||||
|
||||
|
||||
|
||||
// The title of the test case
|
||||
$title = "Testing issue 49 - flexible convolution";
|
||||
|
||||
|
||||
|
||||
// Provide a short description of the testcase.
|
||||
$description = "Creating shortcuts to custom convolutions by using configurable list of constant convolutions.";
|
||||
|
||||
|
||||
|
||||
// Use these images in the test
|
||||
$images = array(
|
||||
'kodim08.png',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// For each image, apply these testcases
|
||||
$testcase = array(
|
||||
'&nc&width=400&convolve=lighten',
|
||||
'&nc&width=400&convolve=darken',
|
||||
'&nc&width=400&convolve=sharpen',
|
||||
'&nc&width=400&convolve=emboss',
|
||||
'&nc&width=400&convolve=blur',
|
||||
'&nc&width=400&convolve=blur:blur',
|
||||
'&nc&width=400&convolve=blur:blur:blur:blur',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Apply testcases and present results
|
||||
include __DIR__ . "/template.php";
|
41
webroot/test/test_issue52-cf.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
// Include config for all testcases
|
||||
include __DIR__ . "/config.php";
|
||||
|
||||
|
||||
|
||||
// The title of the test case
|
||||
$title = "Testing issue 52 - Fill to fit fails with aspect ratio";
|
||||
|
||||
|
||||
|
||||
// Provide a short description of the testcase.
|
||||
$description = "Verify that Fill To Fit resize strategy works with all variants of sizes.";
|
||||
|
||||
|
||||
|
||||
// Use these images in the test
|
||||
$images = array(
|
||||
'car.png',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// For each image, apply these testcases
|
||||
$nc = '&nc';
|
||||
$testcase = array(
|
||||
$nc . '&w=300&h=300&crop-to-fit',
|
||||
$nc . '&w=300&ar=1&crop-to-fit',
|
||||
$nc . '&w=300&ar=3&crop-to-fit',
|
||||
$nc . '&h=300&ar=1&crop-to-fit',
|
||||
$nc . '&h=300&ar=3&crop-to-fit',
|
||||
$nc . '&w=50%&ar=1&crop-to-fit',
|
||||
$nc . '&w=50%&ar=3&crop-to-fit',
|
||||
$nc . '&h=50%&ar=1&crop-to-fit',
|
||||
$nc . '&h=50%&ar=3&crop-to-fit',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Apply testcases and present results
|
||||
include __DIR__ . "/template.php";
|
41
webroot/test/test_issue52-stretch.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
// Include config for all testcases
|
||||
include __DIR__ . "/config.php";
|
||||
|
||||
|
||||
|
||||
// The title of the test case
|
||||
$title = "Testing issue 52 - Fill to fit fails with aspect ratio";
|
||||
|
||||
|
||||
|
||||
// Provide a short description of the testcase.
|
||||
$description = "Verify that Fill To Fit resize strategy works with all variants of sizes.";
|
||||
|
||||
|
||||
|
||||
// Use these images in the test
|
||||
$images = array(
|
||||
'car.png',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// For each image, apply these testcases
|
||||
$nc = '&nc';
|
||||
$testcase = array(
|
||||
$nc . '&w=300&h=300&stretch',
|
||||
$nc . '&w=300&ar=1&stretch',
|
||||
$nc . '&w=300&ar=3&stretch',
|
||||
$nc . '&h=300&ar=1&stretch',
|
||||
$nc . '&h=300&ar=3&stretch',
|
||||
$nc . '&w=50%&ar=1&stretch',
|
||||
$nc . '&w=50%&ar=3&stretch',
|
||||
$nc . '&h=50%&ar=1&stretch',
|
||||
$nc . '&h=50%&ar=3&stretch',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Apply testcases and present results
|
||||
include __DIR__ . "/template.php";
|
41
webroot/test/test_issue52.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
// Include config for all testcases
|
||||
include __DIR__ . "/config.php";
|
||||
|
||||
|
||||
|
||||
// The title of the test case
|
||||
$title = "Testing issue 52 - Fill to fit fails with aspect ratio";
|
||||
|
||||
|
||||
|
||||
// Provide a short description of the testcase.
|
||||
$description = "Verify that Fill To Fit resize strategy works with all variants of sizes.";
|
||||
|
||||
|
||||
|
||||
// Use these images in the test
|
||||
$images = array(
|
||||
'car.png',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// For each image, apply these testcases
|
||||
$nc = null; //&nc';
|
||||
$testcase = array(
|
||||
$nc . '&w=300&h=300&fill-to-fit',
|
||||
$nc . '&w=300&ar=1&fill-to-fit',
|
||||
$nc . '&w=300&ar=2&fill-to-fit',
|
||||
$nc . '&h=300&ar=1&fill-to-fit',
|
||||
$nc . '&h=300&ar=2&fill-to-fit',
|
||||
$nc . '&w=50%&ar=1&fill-to-fit',
|
||||
$nc . '&w=50%&ar=2&fill-to-fit',
|
||||
$nc . '&h=50%&ar=1&fill-to-fit',
|
||||
$nc . '&h=50%&ar=2&fill-to-fit',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Apply testcases and present results
|
||||
include __DIR__ . "/template.php";
|
36
webroot/test/test_issue58.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
// Include config for all testcases
|
||||
include __DIR__ . "/config.php";
|
||||
|
||||
|
||||
|
||||
// The title of the test case
|
||||
$title = "Testing issue 58 - JSON reporting filesize";
|
||||
|
||||
|
||||
|
||||
// Provide a short description of the testcase.
|
||||
$description = "Verify that JSON returns filesize of actual image.";
|
||||
|
||||
|
||||
|
||||
// Use these images in the test
|
||||
$images = array(
|
||||
'kodim08.png',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// For each image, apply these testcases
|
||||
$testcase = array(
|
||||
'&w=300',
|
||||
'&w=300&h=300',
|
||||
'&w=300&h=300&stretch',
|
||||
'&w=300&h=300&crop-to-fit',
|
||||
'&w=300&h=300&fill-to-fit',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Apply testcases and present results
|
||||
include __DIR__ . "/template.php";
|
33
webroot/test/test_issue60.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
// Include config for all testcases
|
||||
include __DIR__ . "/config.php";
|
||||
|
||||
|
||||
|
||||
// The title of the test case
|
||||
$title = "Testing issue 60 - skip original";
|
||||
|
||||
|
||||
|
||||
// Provide a short description of the testcase.
|
||||
$description = "Always use the original if suitable, use skip-original to force using the cached version.";
|
||||
|
||||
|
||||
|
||||
// Use these images in the test
|
||||
$images = array(
|
||||
'car.png',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// For each image, apply these testcases
|
||||
$testcase = array(
|
||||
'',
|
||||
'&so',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Apply testcases and present results
|
||||
include __DIR__ . "/template.php";
|
41
webroot/test/test_option-crop.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
// Include config for all testcases
|
||||
include __DIR__ . "/config.php";
|
||||
|
||||
|
||||
|
||||
// The title of the test case
|
||||
$title = "Testing option crop";
|
||||
|
||||
|
||||
|
||||
// Provide a short description of the testcase.
|
||||
$description = "Cropping parts of image";
|
||||
|
||||
|
||||
|
||||
// Use these images in the test
|
||||
$images = array(
|
||||
'kodim04.png',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// For each image, apply these testcases
|
||||
$nc = "&nc"; //null; //&nc';
|
||||
$testcase = array(
|
||||
$nc . '&w=300',
|
||||
$nc . '&w=300&crop=0,0,0,0',
|
||||
$nc . '&crop=300,200,0,0',
|
||||
$nc . '&crop=300,200,left,top',
|
||||
$nc . '&crop=300,200,right,top',
|
||||
$nc . '&crop=300,200,right,bottom',
|
||||
$nc . '&crop=300,200,left,bottom',
|
||||
$nc . '&crop=300,200,center,center',
|
||||
$nc . '&crop=200,220,190,300',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Apply testcases and present results
|
||||
include __DIR__ . "/template.php";
|
58
webroot/test/test_option-no-upscale.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
// Include config for all testcases
|
||||
include __DIR__ . "/config.php";
|
||||
|
||||
|
||||
|
||||
// The title of the test case
|
||||
$title = "Testing option no-upscale";
|
||||
|
||||
|
||||
|
||||
// Provide a short description of the testcase.
|
||||
$description = "Do not upscale image when original image (slice) is smaller than target image.";
|
||||
|
||||
|
||||
|
||||
// Use these images in the test
|
||||
$images = array(
|
||||
'car.png',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// For each image, apply these testcases
|
||||
$nc = null; //"&nc"; //null; //&nc';
|
||||
$testcase = array(
|
||||
$nc . '&w=600',
|
||||
$nc . '&w=600&no-upscale',
|
||||
$nc . '&h=400',
|
||||
$nc . '&h=400&no-upscale',
|
||||
$nc . '&w=600&h=400',
|
||||
$nc . '&w=600&h=400&no-upscale',
|
||||
$nc . '&w=700&h=400&stretch',
|
||||
$nc . '&w=700&h=400&no-upscale&stretch',
|
||||
$nc . '&w=700&h=200&stretch',
|
||||
$nc . '&w=700&h=200&no-upscale&stretch',
|
||||
$nc . '&w=300&h=400&stretch',
|
||||
$nc . '&w=300&h=400&no-upscale&stretch',
|
||||
$nc . '&w=600&h=400&crop-to-fit',
|
||||
$nc . '&w=600&h=400&no-upscale&crop-to-fit',
|
||||
$nc . '&w=600&h=200&crop-to-fit',
|
||||
$nc . '&w=600&h=200&no-upscale&crop-to-fit',
|
||||
$nc . '&w=300&h=400&crop-to-fit',
|
||||
$nc . '&w=300&h=400&no-upscale&crop-to-fit',
|
||||
$nc . '&w=600&h=400&fill-to-fit',
|
||||
$nc . '&w=600&h=400&no-upscale&fill-to-fit',
|
||||
/*
|
||||
$nc . '&w=600&ar=1.6',
|
||||
$nc . '&w=600&ar=1.6&no-upscale',
|
||||
$nc . '&h=400&ar=1.6',
|
||||
$nc . '&h=400&ar=1.6&no-upscale',
|
||||
*/
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Apply testcases and present results
|
||||
include __DIR__ . "/template.php";
|
42
webroot/test/test_option-save-as.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
// Include config for all testcases
|
||||
include __DIR__ . "/config.php";
|
||||
|
||||
|
||||
|
||||
// The title of the test case
|
||||
$title = "Testing option save-as - save image to another format";
|
||||
|
||||
|
||||
|
||||
// Provide a short description of the testcase.
|
||||
$description = "";
|
||||
|
||||
|
||||
|
||||
// Use these images in the test
|
||||
$images = array(
|
||||
'car.png',
|
||||
'car.gif',
|
||||
'car.jpg',
|
||||
'ball24.png',
|
||||
'wider.jpg',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// For each image, apply these testcases
|
||||
$nc = "&nc"; //null; //&nc';
|
||||
$testcase = array(
|
||||
$nc . '&w=300',
|
||||
$nc . '&w=300&sa=jpg',
|
||||
$nc . '&w=300&sa=png',
|
||||
$nc . '&w=300&sa=gif',
|
||||
$nc . '&w=300&palette',
|
||||
$nc . '&w=300&sa=png&palette',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Apply testcases and present results
|
||||
include __DIR__ . "/template.php";
|