1
0
mirror of https://github.com/mosbth/cimage.git synced 2025-08-06 16:16:39 +02:00

adding images

This commit is contained in:
Mikael Roos
2013-10-07 23:50:53 +02:00
parent 04fd68cb2b
commit 47e5cb2327
15 changed files with 181 additions and 78 deletions

View File

@@ -151,6 +151,7 @@ EOD;
$cropToFit = $this->cropToFit ? '_cf' : null;
$crop_x = $this->crop_x ? "_x{$this->crop_x}" : null;
$crop_y = $this->crop_y ? "_y{$this->crop_y}" : null;
$scale = $this->scale ? "_s{$this->scale}" : null;
$quality = $this->quality ? "_q{$this->quality}" : null;
$offset = isset($this->offset) ? '_o' . $this->offset['top'] . '-' . $this->offset['right'] . '-' . $this->offset['bottom'] . '-' . $this->offset['left'] : null;
$crop = $this->crop ? '_c' . $this->crop['width'] . '-' . $this->crop['height'] . '-' . $this->crop['start_x'] . '-' . $this->crop['start_y'] : null;
@@ -184,7 +185,10 @@ EOD;
$subdir = str_replace('/', '-', dirname($this->imageName));
$subdir = ($subdir == '.') ? '_.' : $subdir;
$this->cacheFileName = $this->saveFolder . '/' . $subdir . '_' . $parts['filename'] . '_' . round($this->newWidth) . '_' . round($this->newHeight) . $offset . $crop . $cropToFit . $crop_x . $crop_y . $quality . $filters . $sharpen . $emboss . $blur . $palette . $optimize . '.' . $this->extension;
$this->cacheFileName = $this->saveFolder . '/' . $subdir . '_' . $parts['filename'] . '_' . round($this->newWidth) . '_' . round($this->newHeight) . $offset . $crop . $cropToFit . $crop_x . $crop_y . $quality . $filters . $sharpen . $emboss . $blur . $palette . $optimize . $scale . '.' . $this->extension;
// Sanitize filename
$this->cacheFileName = preg_replace('/^a-zA-Z0-9\.-_/', '', $this->cacheFileName);
$this->Log("The cache file name is: " . $this->cacheFileName);
return $this;
}
@@ -195,15 +199,6 @@ EOD;
* Init and do some sanity checks before any processing is done. Throws exception if not valid.
*/
public function Init() {
is_null($this->newWidth) or is_numeric($this->newWidth) or $this->RaiseError('Width not numeric');
is_null($this->newHeight) or is_numeric($this->newHeight) or $this->RaiseError('Height not numeric');
is_null($this->quality) or (is_numeric($this->quality) and $this->quality >= 0 and $this->quality <= 100) or $this->RaiseError('Quality not in range.');
//is_numeric($this->crop_x) && is_numeric($this->crop_y) or $this->RaiseError('Quality not in range.');
//filter
is_readable($this->pathToImage) or $this->RaiseError('File does not exist.');
in_array($this->fileExtension, $this->validExtensions) or $this->RaiseError('Not a valid file extension.');
is_null($this->saveFolder) or is_writable($this->saveFolder) or $this->RaiseError('Save directory does not exist or is not writable.');
// Get details on image
$info = list($this->width, $this->height, $this->type, $this->attr) = getimagesize($this->pathToImage);
!empty($info) or $this->RaiseError("The file doesn't seem to be an image.");
@@ -215,6 +210,54 @@ EOD;
$this->Log("Image filesize: " . filesize($this->pathToImage) . " bytes.");
}
// width as %
if($this->newWidth[strlen($this->newWidth)-1] == '%') {
$this->newWidth = $this->width * substr($this->newWidth, 0, -1) / 100;
$this->Log("Setting new width based on % to {$this->newWidth}");
}
// height as %
if($this->newHeight[strlen($this->newHeight)-1] == '%') {
$this->newHeight = $this->height * substr($this->newHeight, 0, -1) / 100;
$this->Log("Setting new height based on % to {$this->newHeight}");
}
is_null($this->aspectRatio) or is_numeric($this->aspectRatio) or $this->RaiseError('Aspect ratio out of range');
// width & height from aspect ratio
if($this->aspectRatio && is_null($this->newWidth) && is_null($this->newHeight)) {
// set new width and height based on current & aspect ratio, but base on largest dimension to only shrink image, not enlarge
if($this->aspectRatio >= 1) {
$this->newWidth = $this->width;
$this->newHeight = $this->width / $this->aspectRatio;
$this->Log("Setting new width & height based on width & aspect ratio (>=1) to (w x h) {$this->newWidth} x {$this->newHeight}");
}
else {
$this->newHeight = $this->height;
$this->newWidth = $this->height * $this->aspectRatio;
$this->Log("Setting new width & height based on width & aspect ratio (<1) to (w x h) {$this->newWidth} x {$this->newHeight}");
}
}
else if($this->aspectRatio && is_null($this->newWidth)) {
$this->newWidth = $this->newHeight * $this->aspectRatio;
$this->Log("Setting new width based on aspect ratio to {$this->newWidth}");
}
else if($this->aspectRatio && is_null($this->newHeight)) {
//$this->newHeight = ($this->aspectRatio >= 0) ? ($this->newWidth / $this->aspectRatio) : ($this->newWidth * $this->aspectRatio);
$this->newHeight = $this->newWidth / $this->aspectRatio;
$this->Log("Setting new height based on aspect ratio to {$this->newHeight}");
}
// Check values to be within domain
is_null($this->newWidth) or is_numeric($this->newWidth) or $this->RaiseError('Width not numeric');
is_null($this->newHeight) or is_numeric($this->newHeight) or $this->RaiseError('Height not numeric');
is_null($this->quality) or (is_numeric($this->quality) and $this->quality > 0 and $this->quality <= 100) or $this->RaiseError('Quality not in range.');
//is_numeric($this->crop_x) && is_numeric($this->crop_y) or $this->RaiseError('Quality not in range.');
//filter
is_readable($this->pathToImage) or $this->RaiseError('File does not exist.');
in_array($this->fileExtension, $this->validExtensions) or $this->RaiseError('Not a valid file extension.');
is_null($this->saveFolder) or is_writable($this->saveFolder) or $this->RaiseError('Save directory does not exist or is not writable.');
return $this;
}
@@ -690,10 +733,13 @@ EOD;
$defaults = array(
'newWidth' => null,
'newHeight' => null,
'aspectRatio' => null,
'keepRatio' => true,
'area' => null, //'0,0,0,0',
'scale' => null,
'cropToFit' => false,
'quality' => null,
'deflate' => null,
'crop' => null, //array('width'=>null, 'height'=>null, 'start_x'=>0, 'start_y'=>0),
'filters' => null,
'verbose' => false,
@@ -745,6 +791,11 @@ EOD;
}
}
// Quick solution when introducing parameter deflate, just map it to quality. Should re-engineer usage of quality and deflate.
if(!isset($this->quality) && isset($this->deflate)) {
$this->quality = $this->deflate;
}
// Merge default arguments with incoming and set properties.
//$args = array_merge_recursive($defaults, $args);
$args = array_merge($defaults, $args);
@@ -816,33 +867,11 @@ EOD;
imagefill($img, 0, 0, $bg);
*/
/*
I have had success doing it like this in the past:
$thumb = imagecreatetruecolor($newwidth, $newheight);
imagealphablending($thumb, false);
imagesavealpha($thumb, true);
$source = imagecreatefrompng($fileName);
imagealphablending($source, true);
imagecopyresampled($thumb, $source, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
imagepng($thumb,$newFilename);
I found the output image quality much better using imagecopyresampled() than imagecopyresized()
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 and or crop the image.
*
@@ -851,6 +880,18 @@ EOD;
$this->Log("Starting to Resize()");
// Scale the original image before starting
if(isset($this->scale)) {
$this->Log("Scale by {$this->scale}%");
$newWidth = $this->width * $this->scale / 100;
$newHeight = $this->height * $this->scale / 100;
$img = $this->CreateImageKeepTransparency($newWidth, $newHeight);
imagecopyresampled($img, $this->image, 0, 0, 0, 0, $newWidth, $newHeight, $this->width, $this->height);
$this->image = $img;
$this->width = $newWidth;
$this->height = $newHeight;
}
// Only use a specified area of the image, $this->offset is defining the area to use
if(isset($this->offset)) {
$this->Log("Offset for area to use, cropping it width={$this->offset['width']}, height={$this->offset['height']}, start_x={$this->offset['left']}, start_y={$this->offset['top']}");
@@ -891,6 +932,8 @@ EOD;
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);
$this->image = $imageResized;
$this->width = $this->newWidth;
$this->height = $this->newHeight;
}
// Resize it

View File

@@ -4,22 +4,13 @@ Image conversion on the fly using PHP
About
-------------------------------------
The `CImage.php` is a PHP class that can resize and crop images on the fly on the server side
and output them to, for example to a webpage. The class preserves a cache of the generated
images and responds with HTTP 304 (not modified) if the image has not changed.
`CImage` is a PHP class which enables scaling, cropping, filtering effects and processing of images 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 `img.php` uses `CImage.php` to resize images. It is a usecase on how to use
the class. `img.php` is useful for webpages which want to dynamically resize the images.
Server-side image processing is a useful tool for any web developer, `img.php` has an easy to use interface and its quite powerful when you integrate it with your website. This is a most useful tool for any web developer who has a need to create and process images for a website.
The file `test.php` has testcases that show the results of `img.php` with different
settings.
This is free software and open source.
Start by reviewing the `test.php`, then have a look at `img.php` and finally go through
`CImage.php`.
CImage lives at github: https://github.com/mosbth/cimage
You can try out a live example at: http://dbwebb.se/kod-exempel/cimage/
Read more on http://dbwebb.se/opensource/cimage
Enjoy!
@@ -29,7 +20,8 @@ Mikael Roos (me@mikaelroos.se)
License
-------------------------------------
Free and opensource software. License according to MIT.
License according to MIT.
Installation
@@ -62,6 +54,14 @@ Now you can access and resize your images through `/image/someimage.jpg?w=80`. V
Usage
-------------------------------------
| Parameter | Explained |
|----------------|----------------------------------------------|
| `src` | `src=img.png` choses the source image to use. |
| `h, height` | `h=200` sets the width to be to max 200px. `h=25%` sets the height to 25% of its original height. |
| `w, width` | `w=200` sets the height to be max 200px. `w=100%` sets the width to 100% of its original width. |
| `ar, aspect-ratio` | Use this as 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 width of 100px. |
`img.php?src=image.jpg&sharpen`
-v, -verbose, Do verbose output and print out a log what happens.
@@ -76,6 +76,7 @@ Usage
-palette to create a palette version of the image with up to 256 colors.
Revision history
-------------------------------------
@@ -97,6 +98,11 @@ v0.3.x (latest)
* 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.
v0.3 (2012-10-02)

116
img.php
View File

@@ -10,6 +10,18 @@
error_reporting(-1);
set_time_limit(20);
// Do some sanity checks
function errorPage($msg) {
header("Status: 404 Not Found");
die('404: ' . $msg);
}
// Custom exception handler
function myExceptionHandler($exception) {
errorPage("<p><b>img.php: Uncaught exception:</b> <p>" . $exception->getMessage() . "</p><pre>" . $exception->getTraceAsString(), "</pre>");
}
set_exception_handler('myExceptionHandler');
// Use preprocessing of images
define('PNG_FILTER', '/usr/local/bin/optipng -q');
@@ -18,15 +30,17 @@ define('JPEG_OPTIMIZE', '/usr/local/bin/jpegtran -copy none -optimize');
// Append ending slash
$cimageClassFile = __DIR__ .'/CImage.php';
$pathToImages = __DIR__.'/img/';
$pathToCache = __DIR__.'/cache/';
$maxWidth = $maxHeight = 2000;
$cimageClassFile = __DIR__.'/CImage.php'; // Where is the class file
$pathToImages = __DIR__.'/img/'; // Where are the image base directory
$pathToCache = __DIR__.'/cache/'; // Where is the cache directory
$gridColumnWidth = 30;
$gridGutterWidth = 10;
$gridColumns = 24;
// settings for do not largen smaller images
// settings for max image dimensions
$maxWidth = $maxHeight = 2000;
$maxScale = 400;
// Set sizes to map constant to value, easier to use with width or height
$sizes = array(
@@ -34,6 +48,17 @@ $sizes = array(
'w2' => 630,
);
// Predefine some common aspect ratios
$aspectRatios = 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,
);
// Add column width to $area, useful for use as predefined size for width (or height).
@@ -44,22 +69,25 @@ for($i = 1; $i <= $gridColumns; $i++) {
// Get input from querystring
$srcImage = isset($_GET['src']) ? $_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;
$cropToFit = isset($_GET['crop-to-fit']) ? true : false;
$area = isset($_GET['area']) ? $_GET['area'] : null;
$crop = isset($_GET['crop']) ? $_GET['crop'] : (isset($_GET['c']) ? $_GET['c'] : null);
$quality = isset($_GET['quality']) ? $_GET['quality'] : (isset($_GET['q']) ? $_GET['q'] : null);
$verbose = (isset($_GET['verbose']) || isset($_GET['v'])) ? true : false;
$useCache = isset($_GET['no-cache']) ? false : true;
$useOriginal = isset($_GET['skip-original']) ? false : true;
$saveAs = isset($_GET['save-as']) ? $_GET['save-as'] : null;
$sharpen = isset($_GET['sharpen']) ? true : null;
$emboss = isset($_GET['emboss']) ? true : null;
$blur = isset($_GET['blur']) ? true : null;
$palette = isset($_GET['palette']) ? true : null;
$srcImage = isset($_GET['src']) ? $_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);
$aspectRatio = isset($_GET['aspect-ratio']) ? $_GET['aspect-ratio'] : (isset($_GET['ar']) ? $_GET['ar'] : null);
$scale = isset($_GET['scale']) ? $_GET['scale'] : (isset($_GET['s']) ? $_GET['s'] : null);
$area = isset($_GET['area']) ? $_GET['area'] : (isset($_GET['a']) ? $_GET['a'] : null);
$crop = isset($_GET['crop']) ? $_GET['crop'] : (isset($_GET['c']) ? $_GET['c'] : null);
$quality = isset($_GET['quality']) ? $_GET['quality'] : (isset($_GET['q']) ? $_GET['q'] : null);
$deflate = isset($_GET['deflate']) ? $_GET['deflate'] : (isset($_GET['d']) ? $_GET['d'] : null);
$saveAs = isset($_GET['save-as']) ? $_GET['save-as'] : (isset($_GET['sa']) ? $_GET['sa'] : null);
$sharpen = isset($_GET['sharpen']) ? true : null;
$emboss = isset($_GET['emboss']) ? true : null;
$blur = isset($_GET['blur']) ? true : null;
$palette = isset($_GET['palette']) || isset($_GET['p']) ? true : false;
$verbose = isset($_GET['verbose']) || isset($_GET['v']) ? true : false;
$useCache = isset($_GET['no-cache']) || isset($_GET['nc']) ? false : true;
$useOriginal = isset($_GET['skip-original']) || isset($_GET['so']) ? false : true;
$keepRatio = isset($_GET['no-ratio']) ? false : (isset($_GET['nr']) ? false : (isset($_GET['stretch']) ? false : true ));
$cropToFit = isset($_GET['crop-to-fit']) ? true : (isset($_GET['cf']) ? true : false);
@@ -71,6 +99,18 @@ if(isset($sizes[$newHeight])) {
$newHeight = $sizes[$newHeight];
}
// Check to replace predefined aspect ratio
$negateAspectRatio = ($aspectRatio[0] == '!') ? true : false;
$aspectRatio = $negateAspectRatio ? substr($aspectRatio, 1) : $aspectRatio;
if(isset($aspectRatios[$aspectRatio])) {
$aspectRatio = $aspectRatios[$aspectRatio];
}
if($negateAspectRatio) {
$aspectRatio = 1 / $aspectRatioConvolution;
}
// Add all filters to an array
@@ -82,21 +122,32 @@ for($i=0; $i<10;$i++) {
if($filter) { $filters[] = $filter; }
}
// Do some sanity checks
function errorPage($msg) {
header("Status: 404 Not Found");
die('404: ' . $msg);
}
// Santize and check domain for incoming parameters. (Move to CImage)
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');
is_null($quality) or ($quality > 0 and $quality <= 100) or errorPage('Quality out of range');
is_null($deflate) or ($defalte > 0 and $deflate <= 9) or errorPage('Deflate out of range');
is_null($scale) or ($scale >= 0 and $quality <= 400) or errorPage('Scale out of range');
is_null($aspectRatio) or is_numeric($aspectRatio) or errorPage('Aspect ratio out of range');
// width
if($newWidth[strlen($newWidth)-1] == '%') {
is_numeric(substr($newWidth, 0, -1)) or errorPage('Width % out of range.');
}
else {
is_null($newWidth) or ($newWidth > 10 && $newWidth <= $maxWidth) or errorPage('Width out of range.');
}
// 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.');
}
@@ -123,10 +174,13 @@ $img = new CImage($srcImage, $pathToImages, $pathToCache);
$img->ResizeAndOutput(array(
'newWidth' => $newWidth,
'newHeight' => $newHeight,
'aspectRatio' => $aspectRatio,
'keepRatio' => $keepRatio,
'cropToFit' => $cropToFit,
'scale' => $scale,
'area' => $area,
'quality' => $quality,
'deflate' => $deflate,
'crop' => $crop,
'filters' => $filters,
'verbose' => $verbose,

BIN
img/ball24.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
img/ball8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

BIN
img/car.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 KiB

BIN
img/kodim04.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 622 KiB

BIN
img/kodim07.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 KiB

BIN
img/kodim08.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 770 KiB

BIN
img/kodim13.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 803 KiB

BIN
img/kodim22.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 684 KiB

BIN
img/kodim23.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 KiB

BIN
img/kodim24.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 681 KiB

BIN
img/round24.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
img/round8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB