mirror of
https://github.com/processwire/processwire.git
synced 2025-08-08 15:57:01 +02:00
Add support for interlaced jpeg images per @horst-n and processwire/processwire-requests#134
This commit is contained in:
@@ -554,7 +554,8 @@ $config->fileContentTypes = array(
|
||||
*
|
||||
* #property bool upscaling Upscale if necessary to reach target size? (1=true, 0=false)
|
||||
* #property bool cropping Crop if necessary to reach target size? (1=true, 0=false)
|
||||
* #property bool autoRotation Automatically correct orientation?
|
||||
* #property bool autoRotation Automatically correct orientation? (1=true, 0=false)
|
||||
* #property bool interlace Use interlaced JPEGs by default? Recommended. (1=true, 0=false)
|
||||
* #property string sharpening Sharpening mode, enter one of: none, soft, medium, strong
|
||||
* #property int quality Image quality, enter a value between 1 and 100, where 100 is highest quality (and largest files)
|
||||
* #property float defaultGamma Default gamma of 0.5 to 4.0 or -1 to disable gamma correction (default=2.0)
|
||||
@@ -566,6 +567,7 @@ $config->imageSizerOptions = array(
|
||||
'upscaling' => true, // upscale if necessary to reach target size?
|
||||
'cropping' => true, // crop if necessary to reach target size?
|
||||
'autoRotation' => true, // automatically correct orientation?
|
||||
'interlace' => false, // use interlaced JPEGs by default? (recommended)
|
||||
'sharpening' => 'soft', // sharpening: none | soft | medium | strong
|
||||
'quality' => 90, // quality: 1-100 where higher is better but bigger
|
||||
'hidpiQuality' => 60, // Same as above quality setting, but specific to hidpi images
|
||||
|
@@ -8,6 +8,7 @@
|
||||
*
|
||||
* @property bool $autoRotation
|
||||
* @property bool $upscaling
|
||||
* @property bool $interlace
|
||||
* @property array|string|bool $cropping
|
||||
* @property int $quality
|
||||
* @property string $sharpening
|
||||
@@ -59,6 +60,14 @@ abstract class ImageSizerEngine extends WireData implements Module, Configurable
|
||||
*/
|
||||
protected $quality = 90;
|
||||
|
||||
/**
|
||||
* Image interlace setting, false or true
|
||||
*
|
||||
* @var bool
|
||||
*
|
||||
*/
|
||||
protected $interlace = false;
|
||||
|
||||
/**
|
||||
* Information about the image (width/height)
|
||||
*
|
||||
@@ -206,6 +215,7 @@ abstract class ImageSizerEngine extends WireData implements Module, Configurable
|
||||
'autoRotation',
|
||||
'upscaling',
|
||||
'cropping',
|
||||
'interlace',
|
||||
'quality',
|
||||
'sharpening',
|
||||
'defaultGamma',
|
||||
@@ -910,6 +920,19 @@ abstract class ImageSizerEngine extends WireData implements Module, Configurable
|
||||
$this->upscaling = $this->getBooleanValue($value);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn on/off interlace
|
||||
*
|
||||
* @param bool $value Whether to upscale or not (default = true)
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
*/
|
||||
public function setInterlace($value = true) {
|
||||
$this->interlace = $this->getBooleanValue($value);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default gamma value: 0.5 - 4.0 | -1
|
||||
@@ -1059,6 +1082,9 @@ abstract class ImageSizerEngine extends WireData implements Module, Configurable
|
||||
case 'upscaling':
|
||||
$this->setUpscaling($value);
|
||||
break;
|
||||
case 'interlace':
|
||||
$this->setInterlace($value);
|
||||
break;
|
||||
case 'sharpening':
|
||||
$this->setSharpening($value);
|
||||
break;
|
||||
@@ -1126,6 +1152,7 @@ abstract class ImageSizerEngine extends WireData implements Module, Configurable
|
||||
'quality' => $this->quality,
|
||||
'cropping' => $this->cropping,
|
||||
'upscaling' => $this->upscaling,
|
||||
'interlace' => $this->interlace,
|
||||
'autoRotation' => $this->autoRotation,
|
||||
'sharpening' => $this->sharpening,
|
||||
'defaultGamma' => $this->defaultGamma,
|
||||
|
@@ -185,6 +185,7 @@ class ImageSizerEngineGD extends ImageSizerEngine {
|
||||
|
||||
// now release the intermediate image and update settings
|
||||
imagedestroy($imageTemp);
|
||||
$imageTemp = null;
|
||||
$this->setImageInfo(imagesx($image), imagesy($image));
|
||||
// $this->cropping = false; // ?? set this to prevent overhead with the following manipulation ??
|
||||
}
|
||||
@@ -202,12 +203,19 @@ class ImageSizerEngineGD extends ImageSizerEngine {
|
||||
|
||||
// this is the case if the original size is requested or a greater size but upscaling is set to false
|
||||
|
||||
// the current version is allready the desired result, we only may have to apply compression where possible
|
||||
$this->sharpening = 'none'; // we set sharpening to none
|
||||
// current version is already the desired result, we only may have to compress JPEGs but leave GIF and PNG as is:
|
||||
if($this->imageType == \IMAGETYPE_PNG || $this->imageType == \IMAGETYPE_GIF) {
|
||||
$result = @copy($srcFilename, $dstFilename);
|
||||
if(isset($image) && is_resource($image)) @imagedestroy($image); // clean up
|
||||
if(isset($image)) $image = null;
|
||||
return $result; // early return !
|
||||
}
|
||||
|
||||
// process JPEGs
|
||||
if(self::checkMemoryForImage(array(imagesx($image), imagesy($image), 3)) === false) {
|
||||
throw new WireException(basename($srcFilename) . " - not enough memory to copy the final image");
|
||||
}
|
||||
$this->sharpening = 'none'; // we set sharpening to none, as the image only gets compressed, but not resized
|
||||
$thumb = imagecreatetruecolor(imagesx($image), imagesy($image)); // create the final memory image
|
||||
$this->prepareImageLayer($thumb, $image);
|
||||
imagecopy($thumb, $image, 0, 0, 0, 0, imagesx($image), imagesy($image)); // copy our intermediate image into the final one
|
||||
@@ -273,6 +281,15 @@ class ImageSizerEngineGD extends ImageSizerEngine {
|
||||
}
|
||||
}
|
||||
|
||||
// optionally apply interlace bit to the final image.
|
||||
// this will result in progressive JPEGs
|
||||
if($this->interlace && \IMAGETYPE_JPEG == $this->imageType) {
|
||||
if(0 == imageinterlace($thumb, 1)) {
|
||||
// log that setting the interlace bit has failed ?
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
// write to file
|
||||
$result = false;
|
||||
switch($this->imageType) {
|
||||
|
@@ -436,6 +436,7 @@ class Pageimage extends Pagefile {
|
||||
$defaultOptions = array(
|
||||
'upscaling' => true,
|
||||
'cropping' => true,
|
||||
'interlace' => false,
|
||||
'sharpening' => 'soft',
|
||||
'quality' => 90,
|
||||
'hidpiQuality' => 40,
|
||||
|
@@ -181,7 +181,7 @@ class ImageSizerEngineIMagick extends ImageSizerEngine {
|
||||
$this->im = new \IMagick();
|
||||
|
||||
// set the working colorspace: COLORSPACE_RGB or COLORSPACE_SRGB ( whats about COLORSPACE_GRAY ??)
|
||||
$this->workspaceColorspace = \IMagick::COLORSPACE_SRGB;
|
||||
$this->workspaceColorspace = \Imagick::COLORSPACE_SRGB;
|
||||
$this->im->setColorspace($this->workspaceColorspace);
|
||||
|
||||
if(!$this->im->readImage($srcFilename)) { // actually we get a filecopy from origFilename to destFilename from PageImage
|
||||
@@ -192,7 +192,7 @@ class ImageSizerEngineIMagick extends ImageSizerEngine {
|
||||
// check validity against image magick
|
||||
if(!$this->im->valid()) {
|
||||
$this->release();
|
||||
throw new WireException(sprintf($this->_("loaded file '%s' is not a valid image", basename($srcFilename))));
|
||||
throw new WireException(sprintf($this->_("loaded file '%s' is not a valid image"), basename($srcFilename)));
|
||||
}
|
||||
|
||||
// get image format
|
||||
@@ -207,12 +207,12 @@ class ImageSizerEngineIMagick extends ImageSizerEngine {
|
||||
// check validity against PW
|
||||
if(!in_array($this->imageFormat, $this->validSourceImageFormats())) {
|
||||
$this->release();
|
||||
throw new WireException(sprintf($this->_("loaded file '%s' is not in the list of valid images", basename($dstFilename))));
|
||||
throw new WireException(sprintf($this->_("loaded file '%s' is not in the list of valid images"), basename($dstFilename)));
|
||||
}
|
||||
|
||||
// check and retrieve different image parts and information: ICC, Colorspace, Colordepth, Metadata, etc
|
||||
$this->imageColorspace = $this->im->getImageColorspace();
|
||||
$this->workspaceColorspace = \IMagick::COLORSPACE_GRAY == $this->imageColorspace ? \IMagick::COLORSPACE_GRAY : $this->workspaceColorspace;
|
||||
$this->workspaceColorspace = \Imagick::COLORSPACE_GRAY == $this->imageColorspace ? \Imagick::COLORSPACE_GRAY : $this->workspaceColorspace;
|
||||
$this->im->setColorspace($this->workspaceColorspace);
|
||||
$this->imageMetadata = $this->im->getImageProfiles('*');
|
||||
if(!is_array($this->imageMetadata)) $this->imageMetadata = array();
|
||||
@@ -311,14 +311,14 @@ class ImageSizerEngineIMagick extends ImageSizerEngine {
|
||||
#return true;
|
||||
|
||||
} else if(2 == $resizemethod) { // 2 = resize with aspect ratio
|
||||
if(!$this->im->resizeImage($finalWidth, $finalHeight, \IMagick::FILTER_LANCZOS, 1)) {
|
||||
if(!$this->im->resizeImage($finalWidth, $finalHeight, \Imagick::FILTER_LANCZOS, 1)) {
|
||||
$this->release();
|
||||
return false;
|
||||
}
|
||||
$this->setImageInfo($this->im->getImageWidth(), $this->im->getImageHeight());
|
||||
|
||||
} else if(4 == $resizemethod) { // 4 = resize and crop from center with aspect ratio
|
||||
if(!$this->im->resizeImage($bgWidth, $bgHeight, \IMagick::FILTER_LANCZOS, 1)) {
|
||||
if(!$this->im->resizeImage($bgWidth, $bgHeight, \Imagick::FILTER_LANCZOS, 1)) {
|
||||
$this->release();
|
||||
return false;
|
||||
}
|
||||
@@ -335,6 +335,11 @@ class ImageSizerEngineIMagick extends ImageSizerEngine {
|
||||
$this->imSharpen($this->sharpening);
|
||||
}
|
||||
|
||||
// optionally apply interlace bit to the final image. This will result in progressive JPEGs
|
||||
if($this->interlace && in_array(strtoupper($this->imageFormat), array('JPG', 'JPEG'))) {
|
||||
$this->im->setInterlaceScheme(\Imagick::INTERLACE_JPEG);
|
||||
}
|
||||
|
||||
if(isset($resetGamma) && $this->imageGamma && $this->imageGamma != 1) {
|
||||
$this->im->gammaImage(1 / $this->imageGamma);
|
||||
}
|
||||
@@ -345,13 +350,13 @@ class ImageSizerEngineIMagick extends ImageSizerEngine {
|
||||
$this->im->setImageFormat($this->imageFormat);
|
||||
$this->im->setImageType($this->imageType);
|
||||
if(in_array(strtoupper($this->imageFormat), array('JPG', 'JPEG'))) {
|
||||
$this->im->setImageCompression(\IMagick::COMPRESSION_JPEG);
|
||||
$this->im->setImageCompression(\Imagick::COMPRESSION_JPEG);
|
||||
$this->im->setImageCompressionQuality($this->quality);
|
||||
} else if(in_array(strtoupper($this->imageFormat), array('PNG', 'PNG8', 'PNG24'))) {
|
||||
$this->im->setImageCompression(\IMagick::COMPRESSION_ZIP);
|
||||
$this->im->setImageCompression(\Imagick::COMPRESSION_ZIP);
|
||||
$this->im->setImageCompressionQuality($this->quality);
|
||||
} else {
|
||||
$this->im->setImageCompression(\IMagick::COMPRESSION_UNDEFINED);
|
||||
$this->im->setImageCompression(\Imagick::COMPRESSION_UNDEFINED);
|
||||
$this->im->setImageCompressionQuality($this->quality);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user