mirror of
https://github.com/mosbth/cimage.git
synced 2025-08-06 16:16:39 +02:00
Added option - no-upscale, nu - as resizing strategy to decline upscaling of smaller images. Fix #61.
This commit is contained in:
89
CImage.php
89
CImage.php
@@ -231,6 +231,14 @@ class CImage
|
|||||||
private $dpr = 1;
|
private $dpr = 1;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Always upscale images, even if they are smaller than target image.
|
||||||
|
*/
|
||||||
|
const UPSCALE_DEFAULT = true;
|
||||||
|
private $upscale = self::UPSCALE_DEFAULT;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Array with details on how to crop, incoming as argument and calculated.
|
* Array with details on how to crop, incoming as argument and calculated.
|
||||||
*/
|
*/
|
||||||
@@ -443,6 +451,7 @@ class CImage
|
|||||||
'fillToFit' => null,
|
'fillToFit' => null,
|
||||||
'crop' => null, //array('width'=>null, 'height'=>null, 'start_x'=>0, 'start_y'=>0),
|
'crop' => null, //array('width'=>null, 'height'=>null, 'start_x'=>0, 'start_y'=>0),
|
||||||
'area' => null, //'0,0,0,0',
|
'area' => null, //'0,0,0,0',
|
||||||
|
'upscale' => self::UPSCALE_DEFAULT,
|
||||||
|
|
||||||
// Options for caching or using original
|
// Options for caching or using original
|
||||||
'useCache' => true,
|
'useCache' => true,
|
||||||
@@ -949,6 +958,7 @@ class CImage
|
|||||||
&& !$this->rotateAfter
|
&& !$this->rotateAfter
|
||||||
&& !$this->autoRotate
|
&& !$this->autoRotate
|
||||||
&& !$this->bgColor
|
&& !$this->bgColor
|
||||||
|
&& ($this->upscale === self::UPSCALE_DEFAULT)
|
||||||
) {
|
) {
|
||||||
$this->log("Using original image.");
|
$this->log("Using original image.");
|
||||||
$this->output($this->pathToImage);
|
$this->output($this->pathToImage);
|
||||||
@@ -1027,11 +1037,16 @@ class CImage
|
|||||||
$convolve = 'convolve' . preg_replace('/[^a-zA-Z0-9]/', '', $this->convolve);
|
$convolve = 'convolve' . preg_replace('/[^a-zA-Z0-9]/', '', $this->convolve);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$upscale = null;
|
||||||
|
if ($this->upscale !== self::UPSCALE_DEFAULT) {
|
||||||
|
$upscale = 'nu';
|
||||||
|
}
|
||||||
|
|
||||||
$subdir = str_replace('/', '-', dirname($this->imageSrc));
|
$subdir = str_replace('/', '-', dirname($this->imageSrc));
|
||||||
$subdir = ($subdir == '.') ? '_.' : $subdir;
|
$subdir = ($subdir == '.') ? '_.' : $subdir;
|
||||||
$file = $subdir . '_' . $parts['filename'] . '_' . $width . '_'
|
$file = $subdir . '_' . $parts['filename'] . '_' . $width . '_'
|
||||||
. $height . $offset . $crop . $cropToFit . $fillToFit
|
. $height . $offset . $crop . $cropToFit . $fillToFit
|
||||||
. $crop_x . $crop_y
|
. $crop_x . $crop_y . $upscale
|
||||||
. $quality . $filters . $sharpen . $emboss . $blur . $palette . $optimize
|
. $quality . $filters . $sharpen . $emboss . $blur . $palette . $optimize
|
||||||
. $scale . $rotateBefore . $rotateAfter . $autoRotate . $bgColor . $convolve
|
. $scale . $rotateBefore . $rotateAfter . $autoRotate . $bgColor . $convolve
|
||||||
. '.' . $this->extension;
|
. '.' . $this->extension;
|
||||||
@@ -1285,6 +1300,7 @@ class CImage
|
|||||||
{
|
{
|
||||||
|
|
||||||
$this->log("Starting to Resize()");
|
$this->log("Starting to Resize()");
|
||||||
|
$this->log("Upscale = '$this->upscale'");
|
||||||
|
|
||||||
// Only use a specified area of the image, $this->offset is defining the area to use
|
// Only use a specified area of the image, $this->offset is defining the area to use
|
||||||
if (isset($this->offset)) {
|
if (isset($this->offset)) {
|
||||||
@@ -1302,7 +1318,6 @@ class CImage
|
|||||||
// Do as crop, take only part of image
|
// Do as crop, take only part of image
|
||||||
$this->log("Cropping area width={$this->crop['width']}, height={$this->crop['height']}, start_x={$this->crop['start_x']}, start_y={$this->crop['start_y']}");
|
$this->log("Cropping area width={$this->crop['width']}, height={$this->crop['height']}, start_x={$this->crop['start_x']}, start_y={$this->crop['start_y']}");
|
||||||
$img = $this->CreateImageKeepTransparency($this->crop['width'], $this->crop['height']);
|
$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']);
|
|
||||||
imagecopy($img, $this->image, 0, 0, $this->crop['start_x'], $this->crop['start_y'], $this->crop['width'], $this->crop['height']);
|
imagecopy($img, $this->image, 0, 0, $this->crop['start_x'], $this->crop['start_y'], $this->crop['width'], $this->crop['height']);
|
||||||
$this->image = $img;
|
$this->image = $img;
|
||||||
$this->width = $this->crop['width'];
|
$this->width = $this->crop['width'];
|
||||||
@@ -1312,22 +1327,26 @@ class CImage
|
|||||||
if ($this->cropToFit) {
|
if ($this->cropToFit) {
|
||||||
|
|
||||||
// Resize by crop to fit
|
// Resize by crop to fit
|
||||||
$this->log("Crop to fit");
|
$this->log("Resizing using strategy - Crop to fit");
|
||||||
$cropX = round(($this->cropWidth/2) - ($this->newWidth/2));
|
|
||||||
$cropY = round(($this->cropHeight/2) - ($this->newHeight/2));
|
if (!$this->upscale && ($this->width < $this->newWidth || $this->height < $this->newHeight)) {
|
||||||
$imgPreCrop = $this->CreateImageKeepTransparency($this->cropWidth, $this->cropHeight);
|
$this->log("Resizing - smaller image, do not upscale.");
|
||||||
$imageResized = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight);
|
} else {
|
||||||
imagecopyresampled($imgPreCrop, $this->image, 0, 0, 0, 0, $this->cropWidth, $this->cropHeight, $this->width, $this->height);
|
$cropX = round(($this->cropWidth/2) - ($this->newWidth/2));
|
||||||
//imagecopyresampled($imageResized, $imgPreCrop, 0, 0, $cropX, $cropY, $this->newWidth, $this->newHeight, $this->newWidth, $this->newHeight);
|
$cropY = round(($this->cropHeight/2) - ($this->newHeight/2));
|
||||||
imagecopy($imageResized, $imgPreCrop, 0, 0, $cropX, $cropY, $this->newWidth, $this->newHeight);
|
$imgPreCrop = $this->CreateImageKeepTransparency($this->cropWidth, $this->cropHeight);
|
||||||
$this->image = $imageResized;
|
$imageResized = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight);
|
||||||
$this->width = $this->newWidth;
|
imagecopyresampled($imgPreCrop, $this->image, 0, 0, 0, 0, $this->cropWidth, $this->cropHeight, $this->width, $this->height);
|
||||||
$this->height = $this->newHeight;
|
imagecopy($imageResized, $imgPreCrop, 0, 0, $cropX, $cropY, $this->newWidth, $this->newHeight);
|
||||||
|
$this->image = $imageResized;
|
||||||
|
$this->width = $this->newWidth;
|
||||||
|
$this->height = $this->newHeight;
|
||||||
|
}
|
||||||
|
|
||||||
} else if ($this->fillToFit) {
|
} else if ($this->fillToFit) {
|
||||||
|
|
||||||
// Resize by fill to fit
|
// Resize by fill to fit
|
||||||
$this->log("Fill to fit");
|
$this->log("Resizing using strategy - Fill to fit");
|
||||||
|
|
||||||
$posX = 0;
|
$posX = 0;
|
||||||
$posY = 0;
|
$posY = 0;
|
||||||
@@ -1342,23 +1361,41 @@ class CImage
|
|||||||
$posY = round(($this->newHeight - $this->fillHeight) / 2);
|
$posY = round(($this->newHeight - $this->fillHeight) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
$imgPreFill = $this->CreateImageKeepTransparency($this->fillWidth, $this->fillHeight);
|
if (!$this->upscale && ($this->width < $this->newWidth || $this->height < $this->newHeight)) {
|
||||||
$imageResized = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight);
|
|
||||||
imagecopyresampled($imgPreFill, $this->image, 0, 0, 0, 0, $this->fillWidth, $this->fillHeight, $this->width, $this->height);
|
$this->log("Resizing - smaller image, do not upscale.");
|
||||||
imagecopy($imageResized, $imgPreFill, $posX, $posY, 0, 0, $this->fillWidth, $this->fillHeight);
|
$posX = round(($this->fillWidth - $this->width) / 2);
|
||||||
$this->image = $imageResized;
|
$posY = round(($this->fillHeight - $this->height) / 2);
|
||||||
$this->width = $this->newWidth;
|
$imageResized = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight);
|
||||||
$this->height = $this->newHeight;
|
imagecopy($imageResized, $this->image, $posX, $posY, 0, 0, $this->fillWidth, $this->fillHeight);
|
||||||
|
$this->image = $imageResized;
|
||||||
|
$this->width = $this->newWidth;
|
||||||
|
$this->height = $this->newHeight;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$imgPreFill = $this->CreateImageKeepTransparency($this->fillWidth, $this->fillHeight);
|
||||||
|
$imageResized = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight);
|
||||||
|
imagecopyresampled($imgPreFill, $this->image, 0, 0, 0, 0, $this->fillWidth, $this->fillHeight, $this->width, $this->height);
|
||||||
|
imagecopy($imageResized, $imgPreFill, $posX, $posY, 0, 0, $this->fillWidth, $this->fillHeight);
|
||||||
|
$this->image = $imageResized;
|
||||||
|
$this->width = $this->newWidth;
|
||||||
|
$this->height = $this->newHeight;
|
||||||
|
}
|
||||||
|
|
||||||
} else if (!($this->newWidth == $this->width && $this->newHeight == $this->height)) {
|
} else if (!($this->newWidth == $this->width && $this->newHeight == $this->height)) {
|
||||||
|
|
||||||
// Resize it
|
// Resize it
|
||||||
$this->log("Resizing, new height and/or width");
|
$this->log("Resizing, new height and/or width");
|
||||||
$imageResized = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight);
|
|
||||||
imagecopyresampled($imageResized, $this->image, 0, 0, 0, 0, $this->newWidth, $this->newHeight, $this->width, $this->height);
|
if (!$this->upscale && ($this->width < $this->newWidth || $this->height < $this->newHeight)) {
|
||||||
$this->image = $imageResized;
|
$this->log("Resizing - smaller image, do not upscale.");
|
||||||
$this->width = $this->newWidth;
|
} else {
|
||||||
$this->height = $this->newHeight;
|
$imageResized = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight);
|
||||||
|
imagecopyresampled($imageResized, $this->image, 0, 0, 0, 0, $this->newWidth, $this->newHeight, $this->width, $this->height);
|
||||||
|
$this->image = $imageResized;
|
||||||
|
$this->width = $this->newWidth;
|
||||||
|
$this->height = $this->newHeight;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
|
@@ -212,6 +212,7 @@ These options affect strategy to use when resizing an image into a target image
|
|||||||
| `nr, no-ratio, stretch` | Do *not* keep aspect ratio when resizing and using both width & height constraints. Results in stretching the image, if needed, to fit in the resulting box. |
|
| `nr, no-ratio, stretch` | Do *not* keep aspect ratio when resizing and using both width & height constraints. Results in stretching the image, if needed, to fit in the resulting box. |
|
||||||
| `cf, crop-to-fit` | Set together with both `h` and `w` to make the image fit into dimensions, and crop out the rest of the image. |
|
| `cf, crop-to-fit` | Set together with both `h` and `w` to make the image fit into dimensions, and crop out the rest of the image. |
|
||||||
| `ff, fill-to-fit` | Set together with both `h` and `w` to make the image fit into dimensions, and fill the rest using a background color. You can optionally supply a background color as this `ff=00ff00`, or `ff=00ff007f` when using the alpha channel. |
|
| `ff, fill-to-fit` | Set together with both `h` and `w` to make the image fit into dimensions, and fill the rest using a background color. You can optionally supply a background color as this `ff=00ff00`, or `ff=00ff007f` when using the alpha channel. |
|
||||||
|
| `nu, no-upscale` | Avoid smaller images from being upscaled to larger ones. Combine with `fill-to-fit` to get the smaller image centered on a larger canvas. |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -280,6 +281,7 @@ Revision history
|
|||||||
|
|
||||||
v0.6.x (latest)
|
v0.6.x (latest)
|
||||||
|
|
||||||
|
* Added option `no-upscale, nu` as resizing strategy to decline upscaling of smaller images. Fix #61.
|
||||||
* Minor change in `CImage::resize()`, crop now does imagecopy without resamling.
|
* Minor change in `CImage::resize()`, crop now does imagecopy without resamling.
|
||||||
* Correcting internal details for save-as and response json which indicated wrong colors. Fix #62.
|
* Correcting internal details for save-as and response json which indicated wrong colors. Fix #62.
|
||||||
* Fixed fill-to-fit that failed when using aspect-ratio. Fix #52.
|
* Fixed fill-to-fit that failed when using aspect-ratio. Fix #52.
|
||||||
|
@@ -529,6 +529,15 @@ verbose("convolve = " . print_r($convolve, 1));
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* no-upscale, nu - Do not upscale smaller image to larger dimension.
|
||||||
|
*/
|
||||||
|
$upscale = getDefined(array('no-upscale', 'nu'), false, true);
|
||||||
|
|
||||||
|
verbose("upscale = $upscale");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display image if verbose mode
|
* Display image if verbose mode
|
||||||
*/
|
*/
|
||||||
@@ -565,6 +574,7 @@ $img->log("Incoming arguments: " . print_r(verbose(), 1))
|
|||||||
'fillToFit' => $fillToFit,
|
'fillToFit' => $fillToFit,
|
||||||
'crop' => $crop,
|
'crop' => $crop,
|
||||||
'area' => $area,
|
'area' => $area,
|
||||||
|
'upscale' => $upscale,
|
||||||
|
|
||||||
// Pre-processing, before resizing is done
|
// Pre-processing, before resizing is done
|
||||||
'scale' => $scale,
|
'scale' => $scale,
|
||||||
|
50
webroot/test/test_option-no-upscale.php
Normal file
50
webroot/test/test_option-no-upscale.php
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
// Include config for all testcases
|
||||||
|
include __DIR__ . "/config.php";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// The title of the test case
|
||||||
|
$title = "Testing option no-upscale";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Provide a short description of the testcase.
|
||||||
|
$description = "Do not upscale image when original image (slice) is smaller than target image.";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Use these images in the test
|
||||||
|
$images = array(
|
||||||
|
'car.png',
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// For each image, apply these testcases
|
||||||
|
$nc = null; //"&nc"; //null; //&nc';
|
||||||
|
$testcase = array(
|
||||||
|
$nc . '&w=600',
|
||||||
|
$nc . '&w=600&no-upscale',
|
||||||
|
$nc . '&h=400',
|
||||||
|
$nc . '&h=400&no-upscale',
|
||||||
|
$nc . '&w=600&h=400',
|
||||||
|
$nc . '&w=600&h=400&no-upscale',
|
||||||
|
$nc . '&w=600&h=400&stretch',
|
||||||
|
$nc . '&w=600&h=400&no-upscale&stretch',
|
||||||
|
$nc . '&w=600&h=400&crop-to-fit',
|
||||||
|
$nc . '&w=600&h=400&no-upscale&crop-to-fit',
|
||||||
|
$nc . '&w=600&h=400&fill-to-fit',
|
||||||
|
$nc . '&w=600&h=400&no-upscale&fill-to-fit',
|
||||||
|
/*
|
||||||
|
$nc . '&w=600&ar=1.6',
|
||||||
|
$nc . '&w=600&ar=1.6&no-upscale',
|
||||||
|
$nc . '&h=400&ar=1.6',
|
||||||
|
$nc . '&h=400&ar=1.6&no-upscale',
|
||||||
|
*/
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Apply testcases and present results
|
||||||
|
include __DIR__ . "/template.php";
|
Reference in New Issue
Block a user