mirror of
https://github.com/mosbth/cimage.git
synced 2025-08-05 23:57:30 +02:00
preparing to tag latest changes
This commit is contained in:
189
CImage.php
189
CImage.php
@@ -12,7 +12,9 @@ class CImage {
|
|||||||
* Properties
|
* Properties
|
||||||
*/
|
*/
|
||||||
private $image = null; // Object for open image
|
private $image = null; // Object for open image
|
||||||
public $pathToImage;
|
public $imageFolder; // root folder of images
|
||||||
|
public $imageName; // image filename, may include subdirectory, relative from $imageFolder
|
||||||
|
public $pathToImage; // $imageFolder . '/' . $imageName;
|
||||||
private $fileExtension;
|
private $fileExtension;
|
||||||
public $newWidth;
|
public $newWidth;
|
||||||
public $newHeight;
|
public $newHeight;
|
||||||
@@ -39,12 +41,15 @@ class CImage {
|
|||||||
/**
|
/**
|
||||||
* Constructor, can take arguments to init the object.
|
* Constructor, can take arguments to init the object.
|
||||||
*
|
*
|
||||||
* @param $pathToImage string the filepath to the image.
|
* @param string $imageName filename which may contain subdirectory.
|
||||||
* @param $saveFolder string path to folder where to save the new file or null to skip saving.
|
* @param string $imageFolder path to root folder for images.
|
||||||
* @param $newName string new filename or leave to null to autogenerate filename.
|
* @param string $saveFolder path to folder where to save the new file or null to skip saving.
|
||||||
|
* @param string $newName new filename or leave to null to autogenerate filename.
|
||||||
*/
|
*/
|
||||||
public function __construct($pathToImage=null, $saveFolder=null, $newName=null) {
|
public function __construct($imageName=null, $imageFolder=null, $saveFolder=null, $newName=null) {
|
||||||
$this->pathToImage = $pathToImage;
|
$this->imageName = ltrim($imageName, '/');
|
||||||
|
$this->imageFolder = rtrim($imageFolder, '/');
|
||||||
|
$this->pathToImage = $this->imageFolder . '/' . $this->imageName;
|
||||||
$this->fileExtension = pathinfo($this->pathToImage, PATHINFO_EXTENSION);
|
$this->fileExtension = pathinfo($this->pathToImage, PATHINFO_EXTENSION);
|
||||||
$this->saveFolder = $saveFolder;
|
$this->saveFolder = $saveFolder;
|
||||||
$this->newName = $newName;
|
$this->newName = $newName;
|
||||||
@@ -66,20 +71,24 @@ class CImage {
|
|||||||
*/
|
*/
|
||||||
public function CreateFilename() {
|
public function CreateFilename() {
|
||||||
$parts = pathinfo($this->pathToImage);
|
$parts = pathinfo($this->pathToImage);
|
||||||
$crop = $this->cropToFit ? '_cf' : null;
|
$cropToFit = $this->cropToFit ? '_cf' : null;
|
||||||
$crop_x = $this->crop_x ? "_x{$this->crop_x}" : null;
|
$crop_x = $this->crop_x ? "_x{$this->crop_x}" : null;
|
||||||
$crop_y = $this->crop_y ? "_y{$this->crop_y}" : null;
|
$crop_y = $this->crop_y ? "_y{$this->crop_y}" : null;
|
||||||
$quality = $this->quality == 100 ? null : "_q{$this->quality}";
|
$quality = $this->quality == 100 ? null : "_q{$this->quality}";
|
||||||
|
$crop = $this->crop ? '_c' . $this->crop['width'] . '-' . $this->crop['height'] . '-' . $this->crop['start_x'] . '-' . $this->crop['start_y'] : null;
|
||||||
$filters = null;
|
$filters = null;
|
||||||
foreach($this->filters as $filter) {
|
if(isset($this->filters)) {
|
||||||
if(is_array($filter)) {
|
foreach($this->filters as $filter) {
|
||||||
$filters .= "_f{$filter['id']}";
|
if(is_array($filter)) {
|
||||||
for($i=1;$i<=$filter['argc'];$i++) {
|
$filters .= "_f{$filter['id']}";
|
||||||
$filters .= ":".$filter["arg{$i}"];
|
for($i=1;$i<=$filter['argc'];$i++) {
|
||||||
|
$filters .= ":".$filter["arg{$i}"];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $this->saveFolder . '/' . $parts['filename'] . '_' . round($this->newWidth) . '_' . round($this->newHeight) . $crop . $crop_x . $crop_y . $quality . $filters . '.' . $parts['extension'];
|
$subdir = str_replace('/', '-', dirname($this->imageName));
|
||||||
|
return $this->saveFolder . '/' . $subdir . '_' . $parts['filename'] . '_' . round($this->newWidth) . '_' . round($this->newHeight) . $crop . $cropToFit . $crop_x . $crop_y . $quality . $filters . '.' . $parts['extension'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -111,7 +120,7 @@ class CImage {
|
|||||||
*/
|
*/
|
||||||
protected function Output($file) {
|
protected function Output($file) {
|
||||||
$time = filemtime($file);
|
$time = filemtime($file);
|
||||||
if(isset($_SERVER['If-Modified-Since']) && strtotime($_SERVER['If-Modified-Since']) >= $time){
|
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $time){
|
||||||
header("HTTP/1.0 304 Not Modified");
|
header("HTTP/1.0 304 Not Modified");
|
||||||
} else {
|
} else {
|
||||||
header('Content-type: ' . $this->mime);
|
header('Content-type: ' . $this->mime);
|
||||||
@@ -120,7 +129,7 @@ class CImage {
|
|||||||
}
|
}
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open image.
|
* Open image.
|
||||||
@@ -170,49 +179,65 @@ class CImage {
|
|||||||
* Calculate new width and height of image.
|
* Calculate new width and height of image.
|
||||||
*/
|
*/
|
||||||
protected function CalculateNewWidthAndHeight() {
|
protected function CalculateNewWidthAndHeight() {
|
||||||
// Only calculate new width and height if keeping aspect-ratio.
|
// Crop, use cropped width and height as base for calulations
|
||||||
|
$width = $this->width;
|
||||||
|
$height = $this->height;
|
||||||
|
if($this->crop) {
|
||||||
|
if(empty($this->crop['width'])) {
|
||||||
|
$this->crop['width'] = $this->width - $this->crop['start_x'];
|
||||||
|
}
|
||||||
|
if(empty($this->crop['height'])) {
|
||||||
|
$this->crop['height'] = $this->height - $this->crop['start_y'];
|
||||||
|
}
|
||||||
|
$width = $this->crop['width'];
|
||||||
|
$height = $this->crop['height'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate new width and height if keeping aspect-ratio.
|
||||||
if($this->keepRatio) {
|
if($this->keepRatio) {
|
||||||
|
|
||||||
// Both new width and height are set.
|
// Both new width and height are set.
|
||||||
if(isset($this->newWidth) && isset($this->newHeight)) {
|
if(isset($this->newWidth) && isset($this->newHeight)) {
|
||||||
|
|
||||||
// Use newWidth and newHeigh as min width/height, image should fit the area.
|
|
||||||
if($this->cropToFit) {
|
|
||||||
$ratioWidth = $this->width/$this->newWidth;
|
|
||||||
$ratioHeight = $this->height/$this->newHeight;
|
|
||||||
$ratio = ($ratioWidth < $ratioHeight) ? $ratioWidth : $ratioHeight;
|
|
||||||
$this->cropWidth = $this->width / $ratio;
|
|
||||||
$this->cropHeight = $this->height / $ratio;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use newWidth and newHeigh as max width/height, image should not be larger.
|
// Use newWidth and newHeigh as max width/height, image should not be larger.
|
||||||
else {
|
$ratioWidth = $width / $this->newWidth;
|
||||||
$ratioWidth = $this->width/$this->newWidth;
|
$ratioHeight = $height / $this->newHeight;
|
||||||
$ratioHeight = $this->height/$this->newHeight;
|
$ratio = ($ratioWidth > $ratioHeight) ? $ratioWidth : $ratioHeight;
|
||||||
$ratio = ($ratioWidth > $ratioHeight) ? $ratioWidth : $ratioHeight;
|
$this->newWidth = $width / $ratio;
|
||||||
$this->newWidth = $this->width / $ratio;
|
$this->newHeight = $height / $ratio;
|
||||||
$this->newHeight = $this->height / $ratio;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use new width as max-width
|
// Use new width as max-width
|
||||||
elseif(isset($this->newWidth)) {
|
elseif(isset($this->newWidth)) {
|
||||||
$factor = (float)$this->newWidth / (float)$this->width;
|
$factor = (float)$this->newWidth / (float)$width;
|
||||||
$this->newHeight = $factor * $this->height;
|
$this->newHeight = $factor * $height;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use new height as max-hight
|
// Use new height as max-hight
|
||||||
elseif(isset($this->newHeight)) {
|
elseif(isset($this->newHeight)) {
|
||||||
$factor = (float)$this->newHeight / (float)$this->height;
|
$factor = (float)$this->newHeight / (float)$height;
|
||||||
$this->newWidth = $factor * $this->width;
|
$this->newWidth = $factor * $width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use newWidth and newHeigh as min width/height, image should fit the area.
|
||||||
|
if($this->cropToFit) {
|
||||||
|
$ratioWidth = $width / $this->newWidth;
|
||||||
|
$ratioHeight = $height / $this->newHeight;
|
||||||
|
$ratio = ($ratioWidth < $ratioHeight) ? $ratioWidth : $ratioHeight;
|
||||||
|
$this->cropWidth = $width / $ratio;
|
||||||
|
$this->cropHeight = $height / $ratio;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not keep aspect ratio, but both newWidth and newHeight must be set
|
// Crop, ensure to set new width and height
|
||||||
else {
|
if($this->crop) {
|
||||||
$this->newWidth = isset($this->newWidth) ? $this->newWidth : $this->width;
|
$this->newWidth = isset($this->newWidth) ? $this->newWidth : $this->crop['width'];
|
||||||
$this->newHeight = isset($this->newHeight) ? $this->newHeight : $this->height;
|
$this->newHeight = isset($this->newHeight) ? $this->newHeight : $this->crop['height'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No new height or width is set, use existing measures.
|
||||||
|
$this->newWidth = round(isset($this->newWidth) ? $this->newWidth : $this->width);
|
||||||
|
$this->newHeight = round(isset($this->newHeight) ? $this->newHeight : $this->height);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,7 +250,7 @@ class CImage {
|
|||||||
* @param boolean $keepRatio true to keep aspect ratio else false. Default is true.
|
* @param boolean $keepRatio true to keep aspect ratio else false. Default is true.
|
||||||
* @param boolean $cropToFit true to crop image to fit in box specified by $newWidth and $newHeight. Default is false.
|
* @param boolean $cropToFit true to crop image to fit in box specified by $newWidth and $newHeight. Default is false.
|
||||||
* @param integer $quality the quality to use when saving the file, range 0-100, default is full quality which is 100.
|
* @param integer $quality the quality to use when saving the file, range 0-100, default is full quality which is 100.
|
||||||
* @param array $crop.
|
* @param array/string $crop converts string of 1,2,3,4 to array 'width'=>1, 'height'=>2, 'start_x'=>3, 'start_y'=>4.
|
||||||
* @param array $filter.
|
* @param array $filter.
|
||||||
*/
|
*/
|
||||||
public function ResizeAndOutput($args) {
|
public function ResizeAndOutput($args) {
|
||||||
@@ -235,12 +260,19 @@ class CImage {
|
|||||||
'keepRatio'=>true,
|
'keepRatio'=>true,
|
||||||
'cropToFit'=>false,
|
'cropToFit'=>false,
|
||||||
'quality'=>100,
|
'quality'=>100,
|
||||||
'crop'=>array('w'=>null, 'h'=>null, 'x'=>0, 'y'=>0),
|
'crop'=>null, //array('width'=>null, 'height'=>null, 'start_x'=>0, 'start_y'=>0),
|
||||||
'filters'=>null,
|
'filters'=>null,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Convert crop settins from string to array
|
// Convert crop settins from string to array
|
||||||
if(isset($args['crop']) && !is_array($args['crop'])) {
|
if(isset($args['crop']) && !is_array($args['crop'])) {
|
||||||
$args['crop'] = array();
|
$pices = explode(',', $args['crop']);
|
||||||
|
$args['crop'] = array(
|
||||||
|
'width' => $pices[0],
|
||||||
|
'height' => $pices[1],
|
||||||
|
'start_x' => $pices[2],
|
||||||
|
'start_y' => $pices[3],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert filter settins from array of string to array of array
|
// Convert filter settins from array of string to array of array
|
||||||
@@ -262,13 +294,16 @@ class CImage {
|
|||||||
//echo "<pre>" . print_r($args['filters'], true) . "</pre>";
|
//echo "<pre>" . print_r($args['filters'], true) . "</pre>";
|
||||||
|
|
||||||
// Merge default arguments with incoming and set properties.
|
// Merge default arguments with incoming and set properties.
|
||||||
|
//$args = array_merge_recursive($defaults, $args);
|
||||||
$args = array_merge($defaults, $args);
|
$args = array_merge($defaults, $args);
|
||||||
foreach($defaults as $key=>$val) {
|
foreach($defaults as $key=>$val) {
|
||||||
$this->{$key} = $args[$key];
|
$this->{$key} = $args[$key];
|
||||||
}
|
}
|
||||||
|
//echo "<pre>" . print_r($this, true) . "</pre>";
|
||||||
|
|
||||||
// Init the object and do sanity checks on arguments
|
// Init the object and do sanity checks on arguments
|
||||||
$this->Init()->CalculateNewWidthAndHeight();
|
$this->Init()->CalculateNewWidthAndHeight();
|
||||||
|
//echo "<pre>" . print_r($this, true) . "</pre>";
|
||||||
|
|
||||||
// Use original image?
|
// Use original image?
|
||||||
if(is_null($this->newWidth) && is_null($this->newHeight)) {
|
if(is_null($this->newWidth) && is_null($this->newHeight)) {
|
||||||
@@ -278,35 +313,75 @@ class CImage {
|
|||||||
// Check cache before resizing.
|
// Check cache before resizing.
|
||||||
$this->newFileName = $this->CreateFilename();
|
$this->newFileName = $this->CreateFilename();
|
||||||
if(is_readable($this->newFileName)) {
|
if(is_readable($this->newFileName)) {
|
||||||
$fileTime = filemtime($this->pathToImage);
|
$fileTime = filemtime($this->pathToImage);
|
||||||
$cacheTime = filemtime($this->newFileName);
|
$cacheTime = filemtime($this->newFileName);
|
||||||
if($fileTime <= $cacheTime) {
|
if($fileTime <= $cacheTime) {
|
||||||
$this->Output($this->newFileName);
|
$this->Output($this->newFileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resize and output
|
// Resize and output and save new to cache
|
||||||
$this->Open()->ResizeAndSave();
|
$this->Open()->ResizeAndSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a image and keep transparency for png and gifs.
|
||||||
|
*
|
||||||
|
* $param int $width of the new image.
|
||||||
|
* @param int $height of the new image.
|
||||||
|
* @returns image resource.
|
||||||
|
*/
|
||||||
|
public function CreateImageKeepTransparency($width, $height) {
|
||||||
|
//echo $width . "x" . $height . "<br>";
|
||||||
|
$img = imagecreatetruecolor($width, $height);
|
||||||
|
|
||||||
|
/*
|
||||||
|
if($this->fileExtension == 'png' || ($this->fileExtension == 'gif')) {
|
||||||
|
imagealphablending($img, false);
|
||||||
|
imagesavealpha($img, true);
|
||||||
|
$transparent = imagecolorallocatealpha($img, 255, 255, 255, 127);
|
||||||
|
imagefilledrectangle($img, 0, 0, $width, $height, $transparent);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
return $img;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resize, crop and output the image.
|
* Resize, crop and output the image.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function ResizeAndSave() {
|
public function ResizeAndSave() {
|
||||||
|
|
||||||
|
// Do as crop, take only part of image
|
||||||
|
if($this->crop) {
|
||||||
|
//echo "Cropping";
|
||||||
|
$img = $this->CreateImageKeepTransparency($this->crop['width'], $this->crop['height']);
|
||||||
|
imagecopyresampled($img, $this->image, 0, 0, $this->crop['start_x'], $this->crop['start_y'], $this->crop['width'], $this->crop['height'], $this->crop['width'], $this->crop['height']);
|
||||||
|
$this->image = $img;
|
||||||
|
$this->width = $this->crop['width'];
|
||||||
|
$this->height = $this->crop['height'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resize by crop to fit
|
||||||
if($this->cropToFit) {
|
if($this->cropToFit) {
|
||||||
|
//echo "Crop to fit";
|
||||||
$cropX = ($this->cropWidth/2) - ($this->newWidth/2);
|
$cropX = ($this->cropWidth/2) - ($this->newWidth/2);
|
||||||
$cropY = ($this->cropHeight/2) - ($this->newHeight/2);
|
$cropY = ($this->cropHeight/2) - ($this->newHeight/2);
|
||||||
$imgPreCrop = imagecreatetruecolor($this->cropWidth, $this->cropHeight);
|
$imgPreCrop = $this->CreateImageKeepTransparency($this->cropWidth, $this->cropHeight);
|
||||||
$imageResized = imagecreatetruecolor($this->newWidth, $this->newHeight);
|
$imageResized = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight);
|
||||||
imagecopyresampled($imgPreCrop, $this->image, 0, 0, 0, 0, $this->cropWidth, $this->cropHeight, $this->width, $this->height);
|
imagecopyresampled($imgPreCrop, $this->image, 0, 0, 0, 0, $this->cropWidth, $this->cropHeight, $this->width, $this->height);
|
||||||
imagecopyresampled($imageResized, $imgPreCrop, 0, 0, $cropX, $cropY, $this->newWidth, $this->newHeight, $this->newWidth, $this->newHeight);
|
imagecopyresampled($imageResized, $imgPreCrop, 0, 0, $cropX, $cropY, $this->newWidth, $this->newHeight, $this->newWidth, $this->newHeight);
|
||||||
} else {
|
}
|
||||||
$imageResized = imagecreatetruecolor($this->newWidth, $this->newHeight);
|
|
||||||
|
// as is
|
||||||
|
else {
|
||||||
|
$imageResized = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight);
|
||||||
imagecopyresampled($imageResized, $this->image, 0, 0, 0, 0, $this->newWidth, $this->newHeight, $this->width, $this->height);
|
imagecopyresampled($imageResized, $this->image, 0, 0, 0, 0, $this->newWidth, $this->newHeight, $this->width, $this->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply filters
|
||||||
if(isset($this->filters) && is_array($this->filters)) {
|
if(isset($this->filters) && is_array($this->filters)) {
|
||||||
foreach($this->filters as $filter) {
|
foreach($this->filters as $filter) {
|
||||||
switch($filter['argc']) {
|
switch($filter['argc']) {
|
||||||
@@ -342,10 +417,10 @@ class CImage {
|
|||||||
|
|
||||||
case 'png':
|
case 'png':
|
||||||
// Scale quality from 0-100 to 0-9 and invert setting as 0 is best, not 9
|
// Scale quality from 0-100 to 0-9 and invert setting as 0 is best, not 9
|
||||||
$quality = 9 - round(($imageQuality/100) * 9);
|
$quality = 9 - round(($this->quality/100) * 9);
|
||||||
if (imagetypes() & IMG_PNG) {
|
if (imagetypes() & IMG_PNG) {
|
||||||
if($this->saveFolder) {
|
if($this->saveFolder) {
|
||||||
imagepng($imageResized, $this->newFileName, $this->quality);
|
imagepng($imageResized, $this->newFileName, $quality);
|
||||||
}
|
}
|
||||||
$imgFunction = 'imagepng';
|
$imgFunction = 'imagepng';
|
||||||
}
|
}
|
||||||
@@ -355,7 +430,7 @@ class CImage {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
header('Content-type: ' . $this->mime);
|
header('Content-type: ' . $this->mime);
|
||||||
header('Last-Modified: ' . gmdate("D, d M Y H:i:s",time()) . " GMT");
|
header('Last-Modified: ' . gmdate("D, d M Y H:i:s", time()) . " GMT");
|
||||||
$imgFunction($imageResized);
|
$imgFunction($imageResized);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
36
README.md
36
README.md
@@ -1,19 +1,23 @@
|
|||||||
Image conversion on the fly using PHP
|
Image conversion on the fly using PHP
|
||||||
=====================================
|
=====================================
|
||||||
|
|
||||||
The `CImage.php` contains a class that can resize and crop images and output them to
|
The `CImage.php` is a class that can resize and crop images and output them to
|
||||||
a webpage. The class has cache of generated images.
|
a webpage. The class preserves a cache of the generated images and responds with
|
||||||
|
HTTP 304 if the image has not changed.
|
||||||
|
|
||||||
The file `img.php` uses `CImage.php` to resize images. It is a usecase on how to use
|
The file `img.php` uses `CImage.php` to resize images. It is a usecase on how to use
|
||||||
the class.
|
the class. `img.php` is useful for webpages which want to dynamically resize the images.
|
||||||
|
|
||||||
The file `test.php` has some testcases that show the results of `img.php` with different
|
The file `test.php` has testcases that show the results of `img.php` with different
|
||||||
settings.
|
settings.
|
||||||
|
|
||||||
Start by reviewing the `test.php`, then have a look at `img.php` and finally go through
|
The file `example.php` makes an example on how to use and integrate `img.php` with your
|
||||||
`CImage.php`.
|
website and shows why this might be a handy tool for content providers.
|
||||||
|
|
||||||
Enjoy.
|
Start by reading the `example.php`, proceed by reviewing the `test.php`, then have a look
|
||||||
|
at `img.php` and finally go through `CImage.php`.
|
||||||
|
|
||||||
|
Enjoy!
|
||||||
|
|
||||||
Mikael Roos (mos@dbwebb.se)
|
Mikael Roos (mos@dbwebb.se)
|
||||||
|
|
||||||
@@ -23,15 +27,24 @@ Revision history
|
|||||||
|
|
||||||
ToDo.
|
ToDo.
|
||||||
|
|
||||||
* crop
|
|
||||||
* Pre-defined sizes.
|
* Pre-defined sizes.
|
||||||
|
* crop-to-fit, add parameter for offset x and y to enable to define which area is the
|
||||||
|
center of the image from which the crop is done.
|
||||||
|
* Show how to integrate with WordPress.
|
||||||
|
|
||||||
|
v0.3 (2012-08-28)
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
* Added `example.php`to walk through a real live example on how to use `img.php` in a
|
||||||
|
website.
|
||||||
|
|
||||||
v0.2 (2012-05-09)
|
v0.2 (2012-05-09)
|
||||||
|
|
||||||
* Implemented filters as in http://php.net/manual/en/function.imagefilter.php
|
* Implemented filters as in http://php.net/manual/en/function.imagefilter.php
|
||||||
* Changed `crop` to `crop_to_fit`, woks the same way.
|
* Changed `crop` to `crop_to_fit`, works the same way.
|
||||||
* Changed arguments to method and sends them in array.
|
* Changed arguments and sends them in array.
|
||||||
* Added quality-setting.
|
* Added quality-setting.
|
||||||
* Added testcases for above.
|
* Added testcases for above.
|
||||||
|
|
||||||
@@ -43,3 +56,6 @@ v0.1.1 (2012-04-27)
|
|||||||
v0.1 (2012-04-25)
|
v0.1 (2012-04-25)
|
||||||
|
|
||||||
* Initial release after rewriting some older code I had lying around.
|
* Initial release after rewriting some older code I had lying around.
|
||||||
|
|
||||||
|
.
|
||||||
|
..: Copyright 2012 by Mikael Roos (me@mikaelroos.se)
|
||||||
|
52
img.php
52
img.php
@@ -1,23 +1,39 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Resize images on the fly using cache.
|
* Resize images on the fly using cache.
|
||||||
*
|
*
|
||||||
|
* @author Mikael Roos mos@dbwebb.se
|
||||||
|
* @example http://dbwebb.se/kod-exempel/cimage/
|
||||||
|
* @link https://github.com/mosbth/cimage
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
error_reporting(-1);
|
error_reporting(-1);
|
||||||
set_time_limit(20);
|
set_time_limit(20);
|
||||||
|
|
||||||
// Append ending slash
|
// Append ending slash
|
||||||
|
$cimageClassFile = __DIR__ .'/CImage.php';
|
||||||
$pathToImages = __DIR__.'/img/';
|
$pathToImages = __DIR__.'/img/';
|
||||||
$pathToCache = __DIR__.'/cache/';
|
$pathToCache = __DIR__.'/cache/';
|
||||||
|
$maxWidth = $maxHeight = 2000;
|
||||||
|
|
||||||
|
// Set areas to map constant to value, easier to use with width or height
|
||||||
|
$area = array(
|
||||||
|
'w1' => 613,
|
||||||
|
);
|
||||||
|
|
||||||
// Get input from querystring
|
// Get input from querystring
|
||||||
$srcImage = isset($_GET['src']) ? $pathToImages . basename($_GET['src']) : null;
|
$srcImage = isset($_GET['src']) ? $_GET['src'] : null;
|
||||||
$newWidth = isset($_GET['width']) ? $_GET['width'] : (isset($_GET['w']) ? $_GET['w'] : 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);
|
$newHeight = isset($_GET['height']) ? $_GET['height'] : (isset($_GET['h']) ? $_GET['h'] : null);
|
||||||
$keepRatio = isset($_GET['no-ratio']) ? false : true;
|
$keepRatio = isset($_GET['no-ratio']) ? false : true;
|
||||||
$cropToFit = isset($_GET['crop-to-fit']) ? true : false;
|
$cropToFit = isset($_GET['crop-to-fit']) ? true : false;
|
||||||
$crop = isset($_GET['crop']) ? $_GET['crop'] : (isset($_GET['c']) ? $_GET['c'] : null);
|
$crop = isset($_GET['crop']) ? $_GET['crop'] : (isset($_GET['c']) ? $_GET['c'] : null);
|
||||||
$quality = isset($_GET['quality']) ? $_GET['quality'] : (isset($_GET['q']) ? $_GET['q'] : 100);
|
$quality = isset($_GET['quality']) ? $_GET['quality'] : (isset($_GET['q']) ? $_GET['q'] : 100);
|
||||||
|
|
||||||
|
// Check to replace area
|
||||||
|
if(isset($area[$newWidth])) {
|
||||||
|
$newWidth = $area[$newWidth];
|
||||||
|
}
|
||||||
|
|
||||||
// Add all filters to an array
|
// Add all filters to an array
|
||||||
$filters = array();
|
$filters = array();
|
||||||
@@ -29,14 +45,22 @@ for($i=0; $i<10;$i++) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Do some sanity checks
|
// Do some sanity checks
|
||||||
!preg_match('/^[\w-\.]+$/', $srcImage) or die('Filename contains invalid characters.');
|
function errorPage($msg) {
|
||||||
is_null($newWidth) or ($newWidth > 10 && $newWidth < 1000) or die('Width out of range.');
|
header("Status: 404 Not Found");
|
||||||
is_null($newHeight) or ($newHeight > 10 && $newHeight < 1000) or die('Hight out of range.');
|
die('404: ' . $msg);
|
||||||
$quality >= 0 and $quality <= 100 or die('Quality out of range');
|
}
|
||||||
|
|
||||||
|
isset($srcImage) or errorPage('Must set src-attribute.');
|
||||||
|
preg_match('#^[a-z0-9A-Z-/_\.]+$#', $srcImage) or errorPage('Filename contains invalid characters.');
|
||||||
|
is_file($pathToImages . '/' . $srcImage) or errorPage('Imagefile does not exists.');
|
||||||
|
is_writable($pathToCache) or errorPage('Cache-directory does not exists or is not writable.');
|
||||||
|
is_null($newWidth) or ($newWidth > 10 && $newWidth <= $maxWidth) or errorPage('Width out of range.');
|
||||||
|
is_null($newHeight) or ($newHeight > 10 && $newHeight <= $maxHeight) or errorPage('Hight out of range.');
|
||||||
|
$quality >= 0 and $quality <= 100 or errorPage('Quality out of range');
|
||||||
|
|
||||||
// Create the image object
|
// Create the image object
|
||||||
require(__DIR__.'/CImage.php');
|
require($cimageClassFile);
|
||||||
$img = new CImage($srcImage, $pathToCache);
|
$img = new CImage($srcImage, $pathToImages, $pathToCache);
|
||||||
$img->ResizeAndOutput(array('newWidth'=>$newWidth, 'newHeight'=>$newHeight, 'keepRatio'=>$keepRatio,
|
$img->ResizeAndOutput(array('newWidth'=>$newWidth, 'newHeight'=>$newHeight, 'keepRatio'=>$keepRatio,
|
||||||
'cropToFit'=>$cropToFit, 'quality'=>$quality,
|
'cropToFit'=>$cropToFit, 'quality'=>$quality,
|
||||||
'crop'=>$crop, 'filters'=>$filters,
|
'crop'=>$crop, 'filters'=>$filters,
|
||||||
|
9
test.php
9
test.php
@@ -9,10 +9,12 @@
|
|||||||
<p>Supported arguments throught the querystring are:</p>
|
<p>Supported arguments throught the querystring are:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>h, height: h=200 sets the height to 200px.
|
|
||||||
<li>w, width: w=200 sets the width to 200px.
|
<li>h, height: h=200 sets the new height to max 200px.
|
||||||
|
<li>w, width: w=200 sets the new width to max 200px.
|
||||||
<li>crop-to-fit: set together with both h & w to make the image fit in the box and crop out the rest.
|
<li>crop-to-fit: set together with both h & w to make the image fit in the box and crop out the rest.
|
||||||
<li>no-ratio: do not keep aspect ratio.
|
<li>no-ratio: do not keep aspect ratio.
|
||||||
|
<li>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.
|
||||||
<li>q, quality: q=70 or quality=70 sets the image quality as value between 0 and 100, default is full quality/100.
|
<li>q, quality: q=70 or quality=70 sets the image quality as value between 0 and 100, default is full quality/100.
|
||||||
<li>f, filter: apply filter to image, f=colorize,0,255,0,0 makes image greener. Supports all filters as defined in <a href='http://php.net/manual/en/function.imagefilter.php'><code>imagefilter()</code></a>
|
<li>f, filter: apply filter to image, f=colorize,0,255,0,0 makes image greener. Supports all filters as defined in <a href='http://php.net/manual/en/function.imagefilter.php'><code>imagefilter()</code></a>
|
||||||
<li>f0-f9: same as f/filter, just add more filters. Applied in order f, f0-f9.
|
<li>f0-f9: same as f/filter, just add more filters. Applied in order f, f0-f9.
|
||||||
@@ -20,7 +22,7 @@
|
|||||||
|
|
||||||
<p>Supports <code>.jpg</code>, <code>.png</code> and <code>.gif</code>.</p>
|
<p>Supports <code>.jpg</code>, <code>.png</code> and <code>.gif</code>.</p>
|
||||||
<p>Sourcecode and issues on github: <a href='https://github.com/mosbth/cimage'>https://github.com/mosbth/cimage</a></p>
|
<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>
|
<p>Copyright 2012, Mikael Roos (mos@dbwebb.se)</p>
|
||||||
|
|
||||||
|
|
||||||
<h2>Testcases</h2>
|
<h2>Testcases</h2>
|
||||||
@@ -28,6 +30,7 @@
|
|||||||
<?php
|
<?php
|
||||||
$testcase = array(
|
$testcase = array(
|
||||||
array('text'=>'Original image', 'query'=>''),
|
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'=>'Max width 200.', 'query'=>'&w=200'),
|
array('text'=>'Max width 200.', 'query'=>'&w=200'),
|
||||||
array('text'=>'Max height 200.', 'query'=>'&h=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'=>'Max width 200 and max height 200.', 'query'=>'&w=200&h=200'),
|
||||||
|
Reference in New Issue
Block a user