1
0
mirror of https://github.com/mosbth/cimage.git synced 2025-09-02 20:22:36 +02:00

Compare commits

..

21 Commits

Author SHA1 Message Date
Mikael Roos
1bd6fc8a2c improving dummy image 2015-10-18 17:15:14 +02:00
Mikael Roos
39b6078d84 travis working again, unintentionally removed the cache dirs 2015-10-18 16:25:50 +02:00
Mikael Roos
e7e73fc38c testin travis 2015-10-18 16:22:42 +02:00
Mikael Roos
fa77908616 testin travis 2015-10-18 16:13:45 +02:00
Mikael Roos
0f05cd06e5 testin travis 2015-10-18 16:11:59 +02:00
Mikael Roos
3d773b502d testint travis 2015-10-18 16:04:48 +02:00
Mikael Roos
575c712bd0 testint travis 2015-10-18 16:02:27 +02:00
Mikael Roos
cdd159e142 testing travis 2015-10-18 15:52:06 +02:00
Mikael Roos
f21cd923f3 testing travis 2015-10-18 15:50:22 +02:00
Mikael Roos
18fb271961 add writable cache dir 2015-10-18 15:48:11 +02:00
Mikael Roos
1fdc701f3d prepare to test v0.7.5 2015-10-18 15:43:43 +02:00
Mikael Roos
dc6e9a8708 test tag 2015-10-18 14:52:17 +02:00
Mikael Roos
d9947251ab prepare to merge 2015-10-18 14:44:27 +02:00
Mikael Roos
0fb00df972 adding feature for creating dummy images, #101 2015-09-17 11:24:30 +02:00
Mikael Roos
f00b2e0cd3 adding feature for creating dummy images, #101 2015-09-17 11:22:50 +02:00
Mikael Roos
fd2ddadc44 Add png compression to generated cache filename, fix #103. 2015-09-16 09:51:04 +02:00
Mikael Roos
ea4794f4a2 remove commented code 2015-09-16 09:19:46 +02:00
Mikael Roos
7af0b6ef8a remove commented code 2015-09-16 09:18:51 +02:00
Mikael Roos
850fb76c8b cleanup unused variables 2015-09-16 09:09:30 +02:00
Mikael Roos
49f5f66ad3 calling setSource(null) should unset imageSrc and pathToImage 2015-09-16 08:26:28 +02:00
Mikael Roos
a787593533 Removing unneded internal variable this->imageFolder 2015-09-16 08:21:32 +02:00
13 changed files with 877 additions and 241 deletions

View File

@@ -113,13 +113,6 @@ class CImage
/**
* The root folder of images (only used in constructor to create $pathToImage?).
*/
private $imageFolder;
/**
* Image filename, may include subdirectory, relative from $imageFolder
*/
@@ -193,6 +186,7 @@ class CImage
* Path to command for filter optimize, for example optipng or null.
*/
private $pngFilter;
private $pngFilterCmd;
@@ -200,13 +194,16 @@ class CImage
* Path to command for deflate optimize, for example pngout or null.
*/
private $pngDeflate;
private $pngDeflateCmd;
/**
* Path to command to optimize jpeg images, for example jpegtran or null.
*/
private $jpegOptimize;
private $jpegOptimize;
private $jpegOptimizeCmd;
/**
@@ -282,6 +279,56 @@ class CImage
private $fillToFit;
/**
* To store value for option scale.
*/
private $scale;
/**
* To store value for option.
*/
private $rotateBefore;
/**
* To store value for option.
*/
private $rotateAfter;
/**
* To store value for option.
*/
private $autoRotate;
/**
* To store value for option.
*/
private $sharpen;
/**
* To store value for option.
*/
private $emboss;
/**
* To store value for option.
*/
private $blur;
/**
* Used with option area to set which parts of the image to use.
*/
@@ -355,9 +402,7 @@ class CImage
public $crop_x;
public $crop_y;
public $filters;
private $type; // Calculated from source image
private $attr; // Calculated from source image
private $useOriginal; // Use original image if possible
@@ -414,9 +459,7 @@ class CImage
/**
* Use cache or not.
*
* @todo clean up how $this->noCache is used in other methods.
*
* @param string $use true or false to use cache.
* @param boolean $use true or false to use cache.
*
* @return $this
*/
@@ -428,6 +471,27 @@ class CImage
/**
* Create and save a dummy image. Use dimensions as stated in
* $this->newWidth, or $width or default to 100 (same for height.
*
* @param integer $width use specified width for image dimension.
* @param integer $height use specified width for image dimension.
*
* @return $this
*/
public function createDummyImage($width = null, $height = null)
{
$this->newWidth = $this->newWidth ?: $width ?: 100;
$this->newHeight = $this->newHeight ?: $height ?: 100;
$this->image = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight);
return $this;
}
/**
* Allow or disallow remote image download.
*
@@ -578,16 +642,18 @@ class CImage
/**
* Set src file.
* Set source file to use as image source.
*
* @param string $src of image.
* @param string $dir as base directory where images are.
* @param string $dir as optional base directory where images are.
*
* @return $this
*/
public function setSource($src, $dir = null)
{
if (!isset($src)) {
$this->imageSrc = null;
$this->pathToImage = null;
return $this;
}
@@ -601,9 +667,9 @@ class CImage
$src = basename($src);
}
$this->imageSrc = ltrim($src, '/');
$this->imageFolder = rtrim($dir, '/');
$this->pathToImage = $this->imageFolder . '/' . $this->imageSrc;
$this->imageSrc = ltrim($src, '/');
$imageFolder = rtrim($dir, '/');
$this->pathToImage = $imageFolder . '/' . $this->imageSrc;
return $this;
}
@@ -614,23 +680,23 @@ class CImage
* Set target file.
*
* @param string $src of target image.
* @param string $dir as base directory where images are stored.
* @param string $dir as optional base directory where images are stored.
* Uses $this->saveFolder if null.
*
* @return $this
*/
public function setTarget($src = null, $dir = null)
{
if (!(isset($src) && isset($dir))) {
if (!isset($src)) {
$this->cacheFileName = null;
return $this;
}
$this->saveFolder = $dir;
$this->cacheFileName = $dir . '/' . $src;
if (isset($dir)) {
$this->saveFolder = rtrim($dir, '/');
}
/* Allow readonly cache
is_writable($this->saveFolder)
or $this->raiseError('Target directory is not writable.');
*/
$this->cacheFileName = $this->saveFolder . '/' . $src;
// Sanitize filename
$this->cacheFileName = preg_replace('/^a-zA-Z0-9\.-_/', '', $this->cacheFileName);
@@ -641,6 +707,18 @@ class CImage
/**
* Get filename of target file.
*
* @return Boolean|String as filename of target or false if not set.
*/
public function getTarget()
{
return $this->cacheFileName;
}
/**
* Set options to use when processing image.
*
@@ -688,11 +766,6 @@ class CImage
// Output format
'outputFormat' => null,
'dpr' => 1,
// Options for saving
//'quality' => null,
//'compress' => null,
//'saveAs' => null,
);
// Convert crop settings from string to array
@@ -1186,13 +1259,15 @@ class CImage
/**
* Generate filename to save file in cache.
*
* @param string $base as basepath for storing file.
* @param string $base as optional basepath for storing file.
* @param boolean $useSubdir use or skip the subdir part when creating the
* filename.
*
* @return $this
*/
public function generateFilename($base)
public function generateFilename($base = null, $useSubdir = true)
{
$parts = pathinfo($this->pathToImage);
$filename = basename($this->pathToImage);
$cropToFit = $this->cropToFit ? '_cf' : null;
$fillToFit = $this->fillToFit ? '_ff' : null;
$crop_x = $this->crop_x ? "_x{$this->crop_x}" : null;
@@ -1234,16 +1309,6 @@ class CImage
$autoRotate = $this->autoRotate ? 'ar' : null;
$this->extension = isset($this->extension)
? $this->extension
: (isset($parts['extension'])
? $parts['extension']
: null);
$extension = empty($this->extension)
? null
: "." . $this->extension;
$optimize = $this->jpegOptimize ? 'o' : null;
$optimize .= $this->pngFilter ? 'f' : null;
$optimize .= $this->pngDeflate ? 'd' : null;
@@ -1258,14 +1323,20 @@ class CImage
$upscale = '_nu';
}
$subdir = str_replace('/', '-', dirname($this->imageSrc));
$subdir = ($subdir == '.') ? '_.' : $subdir;
$file = $subdir . '_' . $parts['filename'] . '_' . $width . '_'
$subdir = null;
if ($useSubdir === true) {
$subdir = str_replace('/', '-', dirname($this->imageSrc));
$subdir = ($subdir == '.') ? '_.' : $subdir;
$subdir .= '_';
}
$file = $subdir . $filename . '_' . $width . '_'
. $height . $offset . $crop . $cropToFit . $fillToFit
. $crop_x . $crop_y . $upscale
. $quality . $filters . $sharpen . $emboss . $blur . $palette . $optimize
. $scale . $rotateBefore . $rotateAfter . $autoRotate . $bgColor . $convolve
. $extension;
. $quality . $filters . $sharpen . $emboss . $blur . $palette
. $optimize . $compress
. $scale . $rotateBefore . $rotateAfter . $autoRotate . $bgColor
. $convolve;
return $this->setTarget($file, $base);
}
@@ -2033,7 +2104,10 @@ class CImage
imagealphablending($img, false);
imagesavealpha($img, true);
$index = imagecolortransparent($this->image);
$index = $this->image
? imagecolortransparent($this->image)
: -1;
if ($index != -1) {
imagealphablending($img, true);
@@ -2106,17 +2180,23 @@ class CImage
/**
* Save image.
*
* @param string $src as target filename.
* @param string $base as base directory where to store images.
* @param string $src as target filename.
* @param string $base as base directory where to store images.
* @param boolean $overwrite or not, default to always overwrite file.
*
* @return $this or false if no folder is set.
*/
public function save($src = null, $base = null)
public function save($src = null, $base = null, $overwrite = true)
{
if (isset($src)) {
$this->setTarget($src, $base);
}
if ($overwrite === false && is_file($this->cacheFileName)) {
$this->Log("Not overwriting file since its already exists and \$overwrite if false.");
return;
}
is_writable($this->saveFolder)
or $this->raiseError('Target directory is not writable.');

View File

@@ -45,14 +45,14 @@ There are several ways of installing. You either install the whole project which
The [sourcode is available on GitHub](https://github.com/mosbth/cimage). Clone, fork or [download as zip](https://github.com/mosbth/cimage/archive/master.zip).
**Latest stable version is v0.7.4 released 2015-09-15.**
**Latest stable version is v0.7.6 released 2015-10-18.**
I prefer cloning like this. Do switch to the latest stable version.
```bash
git clone git://github.com/mosbth/cimage.git
cd cimage
git checkout v0.7.4
git checkout v0.7.6
```
Make the cache-directory writable by the webserver.
@@ -75,7 +75,7 @@ There are some all-included bundles of `img.php` that can be downloaded and used
Dowload the version of your choice like this.
```bash
wget https://github.com/mosbth/cimage/tree/v0.7.4/webroot/imgp.php
wget https://github.com/mosbth/cimage/tree/v0.7.6/webroot/imgp.php
```
Open up the file in your editor and edit the array `$config`. Ensure that the paths to the image directory and the cache directory matches your environment, or create an own config-file for the script.

View File

@@ -5,6 +5,22 @@ Revision history
[![Build Status](https://scrutinizer-ci.com/g/mosbth/cimage/badges/build.png?b=master)](https://scrutinizer-ci.com/g/mosbth/cimage/build-status/master)
v0.7.6 (2015-10-18)
-------------------------------------
* Adding testpage for dummy images `webroot/test/test_issue101-dummy.php`.
* Adding width and height when creating dummy image.
v0.7.5 (2015-10-18)
-------------------------------------
* Adding feature for creating dummy images `src=dummy`, #101.
* Add png compression to generated cache filename, fix #103.
* Removed file prefix from storing images in cache, breaking filenamestructure for cache images.
* Code cleaning in `CImage.php`.
v0.7.4 (2015-09-15)
-------------------------------------

1
cache/README.md vendored
View File

@@ -1 +0,0 @@
This directory must be writable by the webserver.

0
cache/dummy/README.md vendored Normal file
View File

49
test/CImageDummyTest.php Normal file
View File

@@ -0,0 +1,49 @@
<?php
/**
* A testclass
*
*/
class CImageDummyTest extends \PHPUnit_Framework_TestCase
{
/**
* Test
*
* @return void
*/
public function testCreate1()
{
$img = new CImage();
$img->setSaveFolder(CACHE_PATH . "/dummy");
$img->setSource('dummy', CACHE_PATH . "/dummy");
$img->createDummyImage();
$img->generateFilename(null, false);
$img->save(null, null, false);
$filename = $img->getTarget();
$this->assertEquals(basename($filename), "dummy_100_100", "Filename not as expected on dummy image.");
}
/**
* Test
*
* @return void
*/
public function testCreate2()
{
$img = new CImage();
$img->setSaveFolder(CACHE_PATH . "/dummy");
$img->setSource('dummy', CACHE_PATH . "/dummy");
$img->createDummyImage(200, 400);
$img->generateFilename(null, false);
$img->save(null, null, false);
$filename = $img->getTarget();
$this->assertEquals(basename($filename), "dummy_200_400", "Filename not as expected on dummy image.");
}
}

View File

@@ -4,3 +4,6 @@
*
*/
require __DIR__ . "/../autoload.php";
define('IMAGE_PATH', __DIR__ . '/../webroot/img/');
define('CACHE_PATH', __DIR__ . '/../cache/');

View File

@@ -8,7 +8,7 @@
*
*/
$version = "v0.7.4 (2015-09-15)";
$version = "v0.7.6 (2015-10-18)";
@@ -373,10 +373,20 @@ $imagePath = getConfig('image_path', __DIR__ . '/img/');
$imagePathConstraint = getConfig('image_path_constraint', true);
$validFilename = getConfig('valid_filename', '#^[a-z0-9A-Z-/_ \.:]+$#');
// Dummy image feature
$dummyEnabled = getConfig('dummy_enabled', true);
$dummyFilename = getConfig('dummy_filename', 'dummy');
$dummyImage = false;
preg_match($validFilename, $srcImage)
or errorPage('Filename contains invalid characters.');
if ($allowRemote && $img->isRemoteSource($srcImage)) {
if ($dummyEnabled && $srcImage === $dummyFilename) {
// Prepare to create a dummy image and use it as the source image.
$dummyImage = true;
} elseif ($allowRemote && $img->isRemoteSource($srcImage)) {
// If source is a remote file, ignore local file checks.
@@ -933,9 +943,47 @@ if ($verboseFile) {
/**
* Load, process and output the image
*/
/**
* Set basic options for image processing.
*/
/**
* Prepare a dummy image and use it as source image.
*/
if ($dummyImage === true) {
$dummyDir = getConfig('dummy_dir', $cachePath. "/" . $dummyFilename);
is_writable($dummyDir)
or verbose("dummy dir not writable = $dummyDir");
$img->setSaveFolder($dummyDir)
->setSource($dummyFilename, $dummyDir)
->setOptions(
array(
'newWidth' => $newWidth,
'newHeight' => $newHeight,
'bgColor' => $bgColor,
)
)
->setJpegQuality($quality)
->setPngCompression($compress)
->createDummyImage()
->generateFilename(null, false)
->save(null, null, false);
$srcImage = $img->getTarget();
$imagePath = null;
verbose("src (updated) = $srcImage");
}
/**
* Load, process and output the image
*/
$img->log("Incoming arguments: " . print_r(verbose(), 1))
->setSaveFolder($cachePath)
->useCache($useCache)

View File

@@ -13,7 +13,6 @@ return array(
* Default values:
* mode: 'production'
*/
'mode' => 'development',
//'mode' => 'production', // 'development', 'strict'
@@ -109,6 +108,28 @@ return array(
/**
* The name representing a dummy image which is automatically created
* and stored at the defined path. The dummy image can then be used
* inplace of an original image as a placeholder.
* The dummy_dir must be writable and it defaults to a subdir of the
* cache directory.
* Write protect the dummy_dir to prevent creation of new dummy images,
* but continue to use the existing ones.
*
* Default value:
* dummy_enabled: true as default, disable dummy feature by setting
* to false.
* dummy_filename: 'dummy' use this as ?src=dummy to create a dummy image.
* dummy_dir: Defaults to subdirectory of 'cache_path',
* named the same as 'dummy_filename'
*/
//'dummy_enabled' => true,
//'dummy_filename' => 'dummy',
//'dummy_dir' => 'some writable directory',
/**
* Check that the imagefile is a file below 'image_path' using realpath().
* Security constraint to avoid reaching images outside image_path.

View File

@@ -1032,13 +1032,6 @@ class CImage
/**
* The root folder of images (only used in constructor to create $pathToImage?).
*/
private $imageFolder;
/**
* Image filename, may include subdirectory, relative from $imageFolder
*/
@@ -1112,6 +1105,7 @@ class CImage
* Path to command for filter optimize, for example optipng or null.
*/
private $pngFilter;
private $pngFilterCmd;
@@ -1119,13 +1113,16 @@ class CImage
* Path to command for deflate optimize, for example pngout or null.
*/
private $pngDeflate;
private $pngDeflateCmd;
/**
* Path to command to optimize jpeg images, for example jpegtran or null.
*/
private $jpegOptimize;
private $jpegOptimize;
private $jpegOptimizeCmd;
/**
@@ -1201,6 +1198,56 @@ class CImage
private $fillToFit;
/**
* To store value for option scale.
*/
private $scale;
/**
* To store value for option.
*/
private $rotateBefore;
/**
* To store value for option.
*/
private $rotateAfter;
/**
* To store value for option.
*/
private $autoRotate;
/**
* To store value for option.
*/
private $sharpen;
/**
* To store value for option.
*/
private $emboss;
/**
* To store value for option.
*/
private $blur;
/**
* Used with option area to set which parts of the image to use.
*/
@@ -1274,9 +1321,7 @@ class CImage
public $crop_x;
public $crop_y;
public $filters;
private $type; // Calculated from source image
private $attr; // Calculated from source image
private $useOriginal; // Use original image if possible
@@ -1333,9 +1378,7 @@ class CImage
/**
* Use cache or not.
*
* @todo clean up how $this->noCache is used in other methods.
*
* @param string $use true or false to use cache.
* @param boolean $use true or false to use cache.
*
* @return $this
*/
@@ -1347,6 +1390,27 @@ class CImage
/**
* Create and save a dummy image. Use dimensions as stated in
* $this->newWidth, or $width or default to 100 (same for height.
*
* @param integer $width use specified width for image dimension.
* @param integer $height use specified width for image dimension.
*
* @return $this
*/
public function createDummyImage($width = null, $height = null)
{
$this->newWidth = $this->newWidth ?: $width ?: 100;
$this->newHeight = $this->newHeight ?: $height ?: 100;
$this->image = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight);
return $this;
}
/**
* Allow or disallow remote image download.
*
@@ -1497,16 +1561,18 @@ class CImage
/**
* Set src file.
* Set source file to use as image source.
*
* @param string $src of image.
* @param string $dir as base directory where images are.
* @param string $dir as optional base directory where images are.
*
* @return $this
*/
public function setSource($src, $dir = null)
{
if (!isset($src)) {
$this->imageSrc = null;
$this->pathToImage = null;
return $this;
}
@@ -1520,9 +1586,9 @@ class CImage
$src = basename($src);
}
$this->imageSrc = ltrim($src, '/');
$this->imageFolder = rtrim($dir, '/');
$this->pathToImage = $this->imageFolder . '/' . $this->imageSrc;
$this->imageSrc = ltrim($src, '/');
$imageFolder = rtrim($dir, '/');
$this->pathToImage = $imageFolder . '/' . $this->imageSrc;
return $this;
}
@@ -1533,23 +1599,23 @@ class CImage
* Set target file.
*
* @param string $src of target image.
* @param string $dir as base directory where images are stored.
* @param string $dir as optional base directory where images are stored.
* Uses $this->saveFolder if null.
*
* @return $this
*/
public function setTarget($src = null, $dir = null)
{
if (!(isset($src) && isset($dir))) {
if (!isset($src)) {
$this->cacheFileName = null;
return $this;
}
$this->saveFolder = $dir;
$this->cacheFileName = $dir . '/' . $src;
if (isset($dir)) {
$this->saveFolder = rtrim($dir, '/');
}
/* Allow readonly cache
is_writable($this->saveFolder)
or $this->raiseError('Target directory is not writable.');
*/
$this->cacheFileName = $this->saveFolder . '/' . $src;
// Sanitize filename
$this->cacheFileName = preg_replace('/^a-zA-Z0-9\.-_/', '', $this->cacheFileName);
@@ -1560,6 +1626,18 @@ class CImage
/**
* Get filename of target file.
*
* @return Boolean|String as filename of target or false if not set.
*/
public function getTarget()
{
return $this->cacheFileName;
}
/**
* Set options to use when processing image.
*
@@ -1607,11 +1685,6 @@ class CImage
// Output format
'outputFormat' => null,
'dpr' => 1,
// Options for saving
//'quality' => null,
//'compress' => null,
//'saveAs' => null,
);
// Convert crop settings from string to array
@@ -2105,13 +2178,15 @@ class CImage
/**
* Generate filename to save file in cache.
*
* @param string $base as basepath for storing file.
* @param string $base as optional basepath for storing file.
* @param boolean $useSubdir use or skip the subdir part when creating the
* filename.
*
* @return $this
*/
public function generateFilename($base)
public function generateFilename($base = null, $useSubdir = true)
{
$parts = pathinfo($this->pathToImage);
$filename = basename($this->pathToImage);
$cropToFit = $this->cropToFit ? '_cf' : null;
$fillToFit = $this->fillToFit ? '_ff' : null;
$crop_x = $this->crop_x ? "_x{$this->crop_x}" : null;
@@ -2153,16 +2228,6 @@ class CImage
$autoRotate = $this->autoRotate ? 'ar' : null;
$this->extension = isset($this->extension)
? $this->extension
: (isset($parts['extension'])
? $parts['extension']
: null);
$extension = empty($this->extension)
? null
: "." . $this->extension;
$optimize = $this->jpegOptimize ? 'o' : null;
$optimize .= $this->pngFilter ? 'f' : null;
$optimize .= $this->pngDeflate ? 'd' : null;
@@ -2177,14 +2242,20 @@ class CImage
$upscale = '_nu';
}
$subdir = str_replace('/', '-', dirname($this->imageSrc));
$subdir = ($subdir == '.') ? '_.' : $subdir;
$file = $subdir . '_' . $parts['filename'] . '_' . $width . '_'
$subdir = null;
if ($useSubdir === true) {
$subdir = str_replace('/', '-', dirname($this->imageSrc));
$subdir = ($subdir == '.') ? '_.' : $subdir;
$subdir .= '_';
}
$file = $subdir . $filename . '_' . $width . '_'
. $height . $offset . $crop . $cropToFit . $fillToFit
. $crop_x . $crop_y . $upscale
. $quality . $filters . $sharpen . $emboss . $blur . $palette . $optimize
. $scale . $rotateBefore . $rotateAfter . $autoRotate . $bgColor . $convolve
. $extension;
. $quality . $filters . $sharpen . $emboss . $blur . $palette
. $optimize . $compress
. $scale . $rotateBefore . $rotateAfter . $autoRotate . $bgColor
. $convolve;
return $this->setTarget($file, $base);
}
@@ -2952,7 +3023,10 @@ class CImage
imagealphablending($img, false);
imagesavealpha($img, true);
$index = imagecolortransparent($this->image);
$index = $this->image
? imagecolortransparent($this->image)
: -1;
if ($index != -1) {
imagealphablending($img, true);
@@ -3025,17 +3099,23 @@ class CImage
/**
* Save image.
*
* @param string $src as target filename.
* @param string $base as base directory where to store images.
* @param string $src as target filename.
* @param string $base as base directory where to store images.
* @param boolean $overwrite or not, default to always overwrite file.
*
* @return $this or false if no folder is set.
*/
public function save($src = null, $base = null)
public function save($src = null, $base = null, $overwrite = true)
{
if (isset($src)) {
$this->setTarget($src, $base);
}
if ($overwrite === false && is_file($this->cacheFileName)) {
$this->Log("Not overwriting file since its already exists and \$overwrite if false.");
return;
}
is_writable($this->saveFolder)
or $this->raiseError('Target directory is not writable.');
@@ -3401,7 +3481,7 @@ EOD;
*
*/
$version = "v0.7.4 (2015-09-15)";
$version = "v0.7.6 (2015-10-18)";
@@ -3766,10 +3846,20 @@ $imagePath = getConfig('image_path', __DIR__ . '/img/');
$imagePathConstraint = getConfig('image_path_constraint', true);
$validFilename = getConfig('valid_filename', '#^[a-z0-9A-Z-/_ \.:]+$#');
// Dummy image feature
$dummyEnabled = getConfig('dummy_enabled', true);
$dummyFilename = getConfig('dummy_filename', 'dummy');
$dummyImage = false;
preg_match($validFilename, $srcImage)
or errorPage('Filename contains invalid characters.');
if ($allowRemote && $img->isRemoteSource($srcImage)) {
if ($dummyEnabled && $srcImage === $dummyFilename) {
// Prepare to create a dummy image and use it as the source image.
$dummyImage = true;
} elseif ($allowRemote && $img->isRemoteSource($srcImage)) {
// If source is a remote file, ignore local file checks.
@@ -4326,9 +4416,47 @@ if ($verboseFile) {
/**
* Load, process and output the image
*/
/**
* Set basic options for image processing.
*/
/**
* Prepare a dummy image and use it as source image.
*/
if ($dummyImage === true) {
$dummyDir = getConfig('dummy_dir', $cachePath. "/" . $dummyFilename);
is_writable($dummyDir)
or verbose("dummy dir not writable = $dummyDir");
$img->setSaveFolder($dummyDir)
->setSource($dummyFilename, $dummyDir)
->setOptions(
array(
'newWidth' => $newWidth,
'newHeight' => $newHeight,
'bgColor' => $bgColor,
)
)
->setJpegQuality($quality)
->setPngCompression($compress)
->createDummyImage()
->generateFilename(null, false)
->save(null, null, false);
$srcImage = $img->getTarget();
$imagePath = null;
verbose("src (updated) = $srcImage");
}
/**
* Load, process and output the image
*/
$img->log("Incoming arguments: " . print_r(verbose(), 1))
->setSaveFolder($cachePath)
->useCache($useCache)

View File

@@ -1032,13 +1032,6 @@ class CImage
/**
* The root folder of images (only used in constructor to create $pathToImage?).
*/
private $imageFolder;
/**
* Image filename, may include subdirectory, relative from $imageFolder
*/
@@ -1112,6 +1105,7 @@ class CImage
* Path to command for filter optimize, for example optipng or null.
*/
private $pngFilter;
private $pngFilterCmd;
@@ -1119,13 +1113,16 @@ class CImage
* Path to command for deflate optimize, for example pngout or null.
*/
private $pngDeflate;
private $pngDeflateCmd;
/**
* Path to command to optimize jpeg images, for example jpegtran or null.
*/
private $jpegOptimize;
private $jpegOptimize;
private $jpegOptimizeCmd;
/**
@@ -1201,6 +1198,56 @@ class CImage
private $fillToFit;
/**
* To store value for option scale.
*/
private $scale;
/**
* To store value for option.
*/
private $rotateBefore;
/**
* To store value for option.
*/
private $rotateAfter;
/**
* To store value for option.
*/
private $autoRotate;
/**
* To store value for option.
*/
private $sharpen;
/**
* To store value for option.
*/
private $emboss;
/**
* To store value for option.
*/
private $blur;
/**
* Used with option area to set which parts of the image to use.
*/
@@ -1274,9 +1321,7 @@ class CImage
public $crop_x;
public $crop_y;
public $filters;
private $type; // Calculated from source image
private $attr; // Calculated from source image
private $useOriginal; // Use original image if possible
@@ -1333,9 +1378,7 @@ class CImage
/**
* Use cache or not.
*
* @todo clean up how $this->noCache is used in other methods.
*
* @param string $use true or false to use cache.
* @param boolean $use true or false to use cache.
*
* @return $this
*/
@@ -1347,6 +1390,27 @@ class CImage
/**
* Create and save a dummy image. Use dimensions as stated in
* $this->newWidth, or $width or default to 100 (same for height.
*
* @param integer $width use specified width for image dimension.
* @param integer $height use specified width for image dimension.
*
* @return $this
*/
public function createDummyImage($width = null, $height = null)
{
$this->newWidth = $this->newWidth ?: $width ?: 100;
$this->newHeight = $this->newHeight ?: $height ?: 100;
$this->image = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight);
return $this;
}
/**
* Allow or disallow remote image download.
*
@@ -1497,16 +1561,18 @@ class CImage
/**
* Set src file.
* Set source file to use as image source.
*
* @param string $src of image.
* @param string $dir as base directory where images are.
* @param string $dir as optional base directory where images are.
*
* @return $this
*/
public function setSource($src, $dir = null)
{
if (!isset($src)) {
$this->imageSrc = null;
$this->pathToImage = null;
return $this;
}
@@ -1520,9 +1586,9 @@ class CImage
$src = basename($src);
}
$this->imageSrc = ltrim($src, '/');
$this->imageFolder = rtrim($dir, '/');
$this->pathToImage = $this->imageFolder . '/' . $this->imageSrc;
$this->imageSrc = ltrim($src, '/');
$imageFolder = rtrim($dir, '/');
$this->pathToImage = $imageFolder . '/' . $this->imageSrc;
return $this;
}
@@ -1533,23 +1599,23 @@ class CImage
* Set target file.
*
* @param string $src of target image.
* @param string $dir as base directory where images are stored.
* @param string $dir as optional base directory where images are stored.
* Uses $this->saveFolder if null.
*
* @return $this
*/
public function setTarget($src = null, $dir = null)
{
if (!(isset($src) && isset($dir))) {
if (!isset($src)) {
$this->cacheFileName = null;
return $this;
}
$this->saveFolder = $dir;
$this->cacheFileName = $dir . '/' . $src;
if (isset($dir)) {
$this->saveFolder = rtrim($dir, '/');
}
/* Allow readonly cache
is_writable($this->saveFolder)
or $this->raiseError('Target directory is not writable.');
*/
$this->cacheFileName = $this->saveFolder . '/' . $src;
// Sanitize filename
$this->cacheFileName = preg_replace('/^a-zA-Z0-9\.-_/', '', $this->cacheFileName);
@@ -1560,6 +1626,18 @@ class CImage
/**
* Get filename of target file.
*
* @return Boolean|String as filename of target or false if not set.
*/
public function getTarget()
{
return $this->cacheFileName;
}
/**
* Set options to use when processing image.
*
@@ -1607,11 +1685,6 @@ class CImage
// Output format
'outputFormat' => null,
'dpr' => 1,
// Options for saving
//'quality' => null,
//'compress' => null,
//'saveAs' => null,
);
// Convert crop settings from string to array
@@ -2105,13 +2178,15 @@ class CImage
/**
* Generate filename to save file in cache.
*
* @param string $base as basepath for storing file.
* @param string $base as optional basepath for storing file.
* @param boolean $useSubdir use or skip the subdir part when creating the
* filename.
*
* @return $this
*/
public function generateFilename($base)
public function generateFilename($base = null, $useSubdir = true)
{
$parts = pathinfo($this->pathToImage);
$filename = basename($this->pathToImage);
$cropToFit = $this->cropToFit ? '_cf' : null;
$fillToFit = $this->fillToFit ? '_ff' : null;
$crop_x = $this->crop_x ? "_x{$this->crop_x}" : null;
@@ -2153,16 +2228,6 @@ class CImage
$autoRotate = $this->autoRotate ? 'ar' : null;
$this->extension = isset($this->extension)
? $this->extension
: (isset($parts['extension'])
? $parts['extension']
: null);
$extension = empty($this->extension)
? null
: "." . $this->extension;
$optimize = $this->jpegOptimize ? 'o' : null;
$optimize .= $this->pngFilter ? 'f' : null;
$optimize .= $this->pngDeflate ? 'd' : null;
@@ -2177,14 +2242,20 @@ class CImage
$upscale = '_nu';
}
$subdir = str_replace('/', '-', dirname($this->imageSrc));
$subdir = ($subdir == '.') ? '_.' : $subdir;
$file = $subdir . '_' . $parts['filename'] . '_' . $width . '_'
$subdir = null;
if ($useSubdir === true) {
$subdir = str_replace('/', '-', dirname($this->imageSrc));
$subdir = ($subdir == '.') ? '_.' : $subdir;
$subdir .= '_';
}
$file = $subdir . $filename . '_' . $width . '_'
. $height . $offset . $crop . $cropToFit . $fillToFit
. $crop_x . $crop_y . $upscale
. $quality . $filters . $sharpen . $emboss . $blur . $palette . $optimize
. $scale . $rotateBefore . $rotateAfter . $autoRotate . $bgColor . $convolve
. $extension;
. $quality . $filters . $sharpen . $emboss . $blur . $palette
. $optimize . $compress
. $scale . $rotateBefore . $rotateAfter . $autoRotate . $bgColor
. $convolve;
return $this->setTarget($file, $base);
}
@@ -2952,7 +3023,10 @@ class CImage
imagealphablending($img, false);
imagesavealpha($img, true);
$index = imagecolortransparent($this->image);
$index = $this->image
? imagecolortransparent($this->image)
: -1;
if ($index != -1) {
imagealphablending($img, true);
@@ -3025,17 +3099,23 @@ class CImage
/**
* Save image.
*
* @param string $src as target filename.
* @param string $base as base directory where to store images.
* @param string $src as target filename.
* @param string $base as base directory where to store images.
* @param boolean $overwrite or not, default to always overwrite file.
*
* @return $this or false if no folder is set.
*/
public function save($src = null, $base = null)
public function save($src = null, $base = null, $overwrite = true)
{
if (isset($src)) {
$this->setTarget($src, $base);
}
if ($overwrite === false && is_file($this->cacheFileName)) {
$this->Log("Not overwriting file since its already exists and \$overwrite if false.");
return;
}
is_writable($this->saveFolder)
or $this->raiseError('Target directory is not writable.');
@@ -3401,7 +3481,7 @@ EOD;
*
*/
$version = "v0.7.4 (2015-09-15)";
$version = "v0.7.6 (2015-10-18)";
@@ -3766,10 +3846,20 @@ $imagePath = getConfig('image_path', __DIR__ . '/img/');
$imagePathConstraint = getConfig('image_path_constraint', true);
$validFilename = getConfig('valid_filename', '#^[a-z0-9A-Z-/_ \.:]+$#');
// Dummy image feature
$dummyEnabled = getConfig('dummy_enabled', true);
$dummyFilename = getConfig('dummy_filename', 'dummy');
$dummyImage = false;
preg_match($validFilename, $srcImage)
or errorPage('Filename contains invalid characters.');
if ($allowRemote && $img->isRemoteSource($srcImage)) {
if ($dummyEnabled && $srcImage === $dummyFilename) {
// Prepare to create a dummy image and use it as the source image.
$dummyImage = true;
} elseif ($allowRemote && $img->isRemoteSource($srcImage)) {
// If source is a remote file, ignore local file checks.
@@ -4326,9 +4416,47 @@ if ($verboseFile) {
/**
* Load, process and output the image
*/
/**
* Set basic options for image processing.
*/
/**
* Prepare a dummy image and use it as source image.
*/
if ($dummyImage === true) {
$dummyDir = getConfig('dummy_dir', $cachePath. "/" . $dummyFilename);
is_writable($dummyDir)
or verbose("dummy dir not writable = $dummyDir");
$img->setSaveFolder($dummyDir)
->setSource($dummyFilename, $dummyDir)
->setOptions(
array(
'newWidth' => $newWidth,
'newHeight' => $newHeight,
'bgColor' => $bgColor,
)
)
->setJpegQuality($quality)
->setPngCompression($compress)
->createDummyImage()
->generateFilename(null, false)
->save(null, null, false);
$srcImage = $img->getTarget();
$imagePath = null;
verbose("src (updated) = $srcImage");
}
/**
* Load, process and output the image
*/
$img->log("Incoming arguments: " . print_r(verbose(), 1))
->setSaveFolder($cachePath)
->useCache($useCache)

View File

@@ -1032,13 +1032,6 @@ class CImage
/**
* The root folder of images (only used in constructor to create $pathToImage?).
*/
private $imageFolder;
/**
* Image filename, may include subdirectory, relative from $imageFolder
*/
@@ -1112,6 +1105,7 @@ class CImage
* Path to command for filter optimize, for example optipng or null.
*/
private $pngFilter;
private $pngFilterCmd;
@@ -1119,13 +1113,16 @@ class CImage
* Path to command for deflate optimize, for example pngout or null.
*/
private $pngDeflate;
private $pngDeflateCmd;
/**
* Path to command to optimize jpeg images, for example jpegtran or null.
*/
private $jpegOptimize;
private $jpegOptimize;
private $jpegOptimizeCmd;
/**
@@ -1201,6 +1198,56 @@ class CImage
private $fillToFit;
/**
* To store value for option scale.
*/
private $scale;
/**
* To store value for option.
*/
private $rotateBefore;
/**
* To store value for option.
*/
private $rotateAfter;
/**
* To store value for option.
*/
private $autoRotate;
/**
* To store value for option.
*/
private $sharpen;
/**
* To store value for option.
*/
private $emboss;
/**
* To store value for option.
*/
private $blur;
/**
* Used with option area to set which parts of the image to use.
*/
@@ -1274,9 +1321,7 @@ class CImage
public $crop_x;
public $crop_y;
public $filters;
private $type; // Calculated from source image
private $attr; // Calculated from source image
private $useOriginal; // Use original image if possible
@@ -1333,9 +1378,7 @@ class CImage
/**
* Use cache or not.
*
* @todo clean up how $this->noCache is used in other methods.
*
* @param string $use true or false to use cache.
* @param boolean $use true or false to use cache.
*
* @return $this
*/
@@ -1347,6 +1390,27 @@ class CImage
/**
* Create and save a dummy image. Use dimensions as stated in
* $this->newWidth, or $width or default to 100 (same for height.
*
* @param integer $width use specified width for image dimension.
* @param integer $height use specified width for image dimension.
*
* @return $this
*/
public function createDummyImage($width = null, $height = null)
{
$this->newWidth = $this->newWidth ?: $width ?: 100;
$this->newHeight = $this->newHeight ?: $height ?: 100;
$this->image = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight);
return $this;
}
/**
* Allow or disallow remote image download.
*
@@ -1497,16 +1561,18 @@ class CImage
/**
* Set src file.
* Set source file to use as image source.
*
* @param string $src of image.
* @param string $dir as base directory where images are.
* @param string $dir as optional base directory where images are.
*
* @return $this
*/
public function setSource($src, $dir = null)
{
if (!isset($src)) {
$this->imageSrc = null;
$this->pathToImage = null;
return $this;
}
@@ -1520,9 +1586,9 @@ class CImage
$src = basename($src);
}
$this->imageSrc = ltrim($src, '/');
$this->imageFolder = rtrim($dir, '/');
$this->pathToImage = $this->imageFolder . '/' . $this->imageSrc;
$this->imageSrc = ltrim($src, '/');
$imageFolder = rtrim($dir, '/');
$this->pathToImage = $imageFolder . '/' . $this->imageSrc;
return $this;
}
@@ -1533,23 +1599,23 @@ class CImage
* Set target file.
*
* @param string $src of target image.
* @param string $dir as base directory where images are stored.
* @param string $dir as optional base directory where images are stored.
* Uses $this->saveFolder if null.
*
* @return $this
*/
public function setTarget($src = null, $dir = null)
{
if (!(isset($src) && isset($dir))) {
if (!isset($src)) {
$this->cacheFileName = null;
return $this;
}
$this->saveFolder = $dir;
$this->cacheFileName = $dir . '/' . $src;
if (isset($dir)) {
$this->saveFolder = rtrim($dir, '/');
}
/* Allow readonly cache
is_writable($this->saveFolder)
or $this->raiseError('Target directory is not writable.');
*/
$this->cacheFileName = $this->saveFolder . '/' . $src;
// Sanitize filename
$this->cacheFileName = preg_replace('/^a-zA-Z0-9\.-_/', '', $this->cacheFileName);
@@ -1560,6 +1626,18 @@ class CImage
/**
* Get filename of target file.
*
* @return Boolean|String as filename of target or false if not set.
*/
public function getTarget()
{
return $this->cacheFileName;
}
/**
* Set options to use when processing image.
*
@@ -1607,11 +1685,6 @@ class CImage
// Output format
'outputFormat' => null,
'dpr' => 1,
// Options for saving
//'quality' => null,
//'compress' => null,
//'saveAs' => null,
);
// Convert crop settings from string to array
@@ -2105,13 +2178,15 @@ class CImage
/**
* Generate filename to save file in cache.
*
* @param string $base as basepath for storing file.
* @param string $base as optional basepath for storing file.
* @param boolean $useSubdir use or skip the subdir part when creating the
* filename.
*
* @return $this
*/
public function generateFilename($base)
public function generateFilename($base = null, $useSubdir = true)
{
$parts = pathinfo($this->pathToImage);
$filename = basename($this->pathToImage);
$cropToFit = $this->cropToFit ? '_cf' : null;
$fillToFit = $this->fillToFit ? '_ff' : null;
$crop_x = $this->crop_x ? "_x{$this->crop_x}" : null;
@@ -2153,16 +2228,6 @@ class CImage
$autoRotate = $this->autoRotate ? 'ar' : null;
$this->extension = isset($this->extension)
? $this->extension
: (isset($parts['extension'])
? $parts['extension']
: null);
$extension = empty($this->extension)
? null
: "." . $this->extension;
$optimize = $this->jpegOptimize ? 'o' : null;
$optimize .= $this->pngFilter ? 'f' : null;
$optimize .= $this->pngDeflate ? 'd' : null;
@@ -2177,14 +2242,20 @@ class CImage
$upscale = '_nu';
}
$subdir = str_replace('/', '-', dirname($this->imageSrc));
$subdir = ($subdir == '.') ? '_.' : $subdir;
$file = $subdir . '_' . $parts['filename'] . '_' . $width . '_'
$subdir = null;
if ($useSubdir === true) {
$subdir = str_replace('/', '-', dirname($this->imageSrc));
$subdir = ($subdir == '.') ? '_.' : $subdir;
$subdir .= '_';
}
$file = $subdir . $filename . '_' . $width . '_'
. $height . $offset . $crop . $cropToFit . $fillToFit
. $crop_x . $crop_y . $upscale
. $quality . $filters . $sharpen . $emboss . $blur . $palette . $optimize
. $scale . $rotateBefore . $rotateAfter . $autoRotate . $bgColor . $convolve
. $extension;
. $quality . $filters . $sharpen . $emboss . $blur . $palette
. $optimize . $compress
. $scale . $rotateBefore . $rotateAfter . $autoRotate . $bgColor
. $convolve;
return $this->setTarget($file, $base);
}
@@ -2952,7 +3023,10 @@ class CImage
imagealphablending($img, false);
imagesavealpha($img, true);
$index = imagecolortransparent($this->image);
$index = $this->image
? imagecolortransparent($this->image)
: -1;
if ($index != -1) {
imagealphablending($img, true);
@@ -3025,17 +3099,23 @@ class CImage
/**
* Save image.
*
* @param string $src as target filename.
* @param string $base as base directory where to store images.
* @param string $src as target filename.
* @param string $base as base directory where to store images.
* @param boolean $overwrite or not, default to always overwrite file.
*
* @return $this or false if no folder is set.
*/
public function save($src = null, $base = null)
public function save($src = null, $base = null, $overwrite = true)
{
if (isset($src)) {
$this->setTarget($src, $base);
}
if ($overwrite === false && is_file($this->cacheFileName)) {
$this->Log("Not overwriting file since its already exists and \$overwrite if false.");
return;
}
is_writable($this->saveFolder)
or $this->raiseError('Target directory is not writable.');
@@ -3401,7 +3481,7 @@ EOD;
*
*/
$version = "v0.7.4 (2015-09-15)";
$version = "v0.7.6 (2015-10-18)";
@@ -3766,10 +3846,20 @@ $imagePath = getConfig('image_path', __DIR__ . '/img/');
$imagePathConstraint = getConfig('image_path_constraint', true);
$validFilename = getConfig('valid_filename', '#^[a-z0-9A-Z-/_ \.:]+$#');
// Dummy image feature
$dummyEnabled = getConfig('dummy_enabled', true);
$dummyFilename = getConfig('dummy_filename', 'dummy');
$dummyImage = false;
preg_match($validFilename, $srcImage)
or errorPage('Filename contains invalid characters.');
if ($allowRemote && $img->isRemoteSource($srcImage)) {
if ($dummyEnabled && $srcImage === $dummyFilename) {
// Prepare to create a dummy image and use it as the source image.
$dummyImage = true;
} elseif ($allowRemote && $img->isRemoteSource($srcImage)) {
// If source is a remote file, ignore local file checks.
@@ -4326,9 +4416,47 @@ if ($verboseFile) {
/**
* Load, process and output the image
*/
/**
* Set basic options for image processing.
*/
/**
* Prepare a dummy image and use it as source image.
*/
if ($dummyImage === true) {
$dummyDir = getConfig('dummy_dir', $cachePath. "/" . $dummyFilename);
is_writable($dummyDir)
or verbose("dummy dir not writable = $dummyDir");
$img->setSaveFolder($dummyDir)
->setSource($dummyFilename, $dummyDir)
->setOptions(
array(
'newWidth' => $newWidth,
'newHeight' => $newHeight,
'bgColor' => $bgColor,
)
)
->setJpegQuality($quality)
->setPngCompression($compress)
->createDummyImage()
->generateFilename(null, false)
->save(null, null, false);
$srcImage = $img->getTarget();
$imagePath = null;
verbose("src (updated) = $srcImage");
}
/**
* Load, process and output the image
*/
$img->log("Incoming arguments: " . print_r(verbose(), 1))
->setSaveFolder($cachePath)
->useCache($useCache)

View File

@@ -0,0 +1,36 @@
<?php
// Include config for all testcases
include __DIR__ . "/config.php";
// The title of the test case
$title = "Testing issue 100 - Dummy images";
// Provide a short description of the testcase.
$description = "Create dummy images.";
// Use these images in the test
$images = array(
'dummy',
);
// For each image, apply these testcases
$testcase = array(
'&nc&so',
'&nc&width=300',
'&nc&height=300',
'&nc&width=300&height=300',
'&nc&bgc=006600',
);
// Apply testcases and present results
include __DIR__ . "/template.php";