protected function thumbnail_image($dst_w, $dst_h, $filter_name = 'FILTER_TRIANGLE', $strip_meta = true)
{
$allowed_filters = array('FILTER_POINT', 'FILTER_BOX', 'FILTER_TRIANGLE', 'FILTER_HERMITE', 'FILTER_HANNING', 'FILTER_HAMMING', 'FILTER_BLACKMAN', 'FILTER_GAUSSIAN', 'FILTER_QUADRATIC', 'FILTER_CUBIC', 'FILTER_CATROM', 'FILTER_MITCHELL', 'FILTER_LANCZOS', 'FILTER_BESSEL', 'FILTER_SINC');
/**
* Set the filter value if '$filter_name' name is in our whitelist and the related
* Imagick constant is defined or fall back to our default filter.
*/
if (in_array($filter_name, $allowed_filters) && defined('Imagick::' . $filter_name)) {
$filter = constant('Imagick::' . $filter_name);
} else {
$filter = defined('Imagick::FILTER_TRIANGLE') ? Imagick::FILTER_TRIANGLE : false;
}
/**
* Filters whether to strip metadata from images when they're resized.
*
* This filter only applies when resizing using the Imagick editor since GD
* always strips profiles by default.
*
* @since 4.5.0
*
* @param bool $strip_meta Whether to strip image metadata during resizing. Default true.
*/
if (apply_filters('image_strip_meta', $strip_meta)) {
$this->strip_meta();
// Fail silently if not supported.
}
try {
/*
* To be more efficient, resample large images to 5x the destination size before resizing
* whenever the output size is less that 1/3 of the original image size (1/3^2 ~= .111),
* unless we would be resampling to a scale smaller than 128x128.
*/
if (is_callable(array($this->image, 'sampleImage'))) {
$resize_ratio = $dst_w / $this->size['width'] * ($dst_h / $this->size['height']);
$sample_factor = 5;
if ($resize_ratio < 0.111 && ($dst_w * $sample_factor > 128 && $dst_h * $sample_factor > 128)) {
$this->image->sampleImage($dst_w * $sample_factor, $dst_h * $sample_factor);
}
}
/*
* Use resizeImage() when it's available and a valid filter value is set.
* Otherwise, fall back to the scaleImage() method for resizing, which
* results in better image quality over resizeImage() with default filter
* settings and retains backward compatibility with pre 4.5 functionality.
*/
if (is_callable(array($this->image, 'resizeImage')) && $filter) {
$this->image->setOption('filter:support', '2.0');
$this->image->resizeImage($dst_w, $dst_h, $filter, 1);
} else {
$this->image->scaleImage($dst_w, $dst_h);
}
// Set appropriate quality settings after resizing.
if ('image/jpeg' == $this->mime_type) {
if (is_callable(array($this->image, 'unsharpMaskImage'))) {
$this->image->unsharpMaskImage(0.25, 0.25, 8, 0.065);
}
$this->image->setOption('jpeg:fancy-upsampling', 'off');
}
if ('image/png' === $this->mime_type) {
$this->image->setOption('png:compression-filter', '5');
$this->image->setOption('png:compression-level', '9');
$this->image->setOption('png:compression-strategy', '1');
$this->image->setOption('png:exclude-chunk', 'all');
}
/*
* If alpha channel is not defined, set it opaque.
*
* Note that Imagick::getImageAlphaChannel() is only available if Imagick
* has been compiled against ImageMagick version 6.4.0 or newer.
*/
if (is_callable(array($this->image, 'getImageAlphaChannel')) && is_callable(array($this->image, 'setImageAlphaChannel')) && defined('Imagick::ALPHACHANNEL_UNDEFINED') && defined('Imagick::ALPHACHANNEL_OPAQUE')) {
if ($this->image->getImageAlphaChannel() === Imagick::ALPHACHANNEL_UNDEFINED) {
$this->image->setImageAlphaChannel(Imagick::ALPHACHANNEL_OPAQUE);
}
}
// Limit the bit depth of resized images to 8 bits per channel.
if (is_callable(array($this->image, 'getImageDepth')) && is_callable(array($this->image, 'setImageDepth'))) {
if (8 < $this->image->getImageDepth()) {
$this->image->setImageDepth(8);
}
}
if (is_callable(array($this->image, 'setInterlaceScheme')) && defined('Imagick::INTERLACE_NO')) {
$this->image->setInterlaceScheme(Imagick::INTERLACE_NO);
}
} catch (Exception $e) {
return new WP_Error('image_resize_error', $e->getMessage());
}
}