预先注意:下面的答案还没有完成,也没有测试,但我没有足够的时间,所以我将把它作为草稿留在这里。可能需要第二双眼睛的是质量方法和version_compare()
.
首先,我们需要一个切入点。在阅读make post 同样,我认为最好是在图像编辑器保存新创建的图像之前跳进去。这是一个微控制器,在连接到image_editor_save_pre
并加载一个类,该类将遍历回调中定义的设置wpse_jpeg_quality
. 它只返回jpeg_quality
在图像编辑器中运行的过滤器。
<?php
namespace WPSE;
/**
* Plugin Name: (#138751) JPEG Quality Router
* Author: Franz Josef Kaiser
* Author URI: http://unserkaiser.com
* License: CC-BY-SA 2.5
*/
add_filter( \'image_editor_save_pre\', \'WPSE\\JPEGQualityController\', 20, 2 );
/**
* @param string $image
* @param int $post_id
* @return string
*/
function JPEGQualityController( $image, $post_id )
{
$config = apply_filters( \'wpse_jpeg_quality\', array(
# Valid: <, lt, <=, le, >, gt, >=, ge, ==, =, eq
\'limit\' => \'gt\',
# Valid: h, w
\'reference\' => \'w\',
\'breakpoint\' => 50,
\'low\' => 80,
\'high\' => 100,
) );
include_once plugin_dir_path( __FILE__ ).\'worker.php\';
new \\WPSE\\JPEGQualityWorker( $image, $config );
return $image;
}
实际工人是
JPEGQualityWorker
班它与上面的主插件文件位于同一目录中,名为
worker.php
(或者您更改上面的控制器)。
它检索图像和您的设置,然后将回调添加到jpeg_quality
滤器is的功能是
检索图像参考(宽度或高度)
质疑决定在哪里切换低质量/压缩比和高质量/压缩比的断点检索原始图像大小决定返回什么质量断点和限制是决定高低的关键,如上所述,这可能需要更多的关注。
<?php
namespace WPSE;
/**
* Class JPEGQualityWorker
* @package WPSE
*/
class JPEGQualityWorker
{
protected $config, $image;
/**
* @param string $image
* @param array $config
*/
public function __construct( Array $config, $image )
{
$this->config = $config;
$this->image = $image;
add_filter( \'jpeg_quality\', array( $this, \'setQuality\' ), 20, 2 );
}
/**
* Return the JPEG compression ratio.
*
* Avoids running in multiple context, as WP runs the function multiple
* times per resize/upload/edit task, which leads to over compressed images.
*
* @param int $compression
* @param string $context Context: edit_image/image_resize/wp_crop_image
* @return int
*/
public function setQuality( $compression, $context )
{
if ( in_array( $context, array(
\'edit_image\',
\'wp_crop_image\',
) ) )
return 100;
$c = $this->getCompression( $this->config, $this->image );
return ! is_wp_error( $c )
? $c
: 100;
}
/**
* @param array $config
* @param string $image
* @return int|string|\\WP_Error
*/
public function getCompression( Array $config, $image )
{
$reference = $this->getReference( $config );
if ( is_wp_error( $reference ) )
return $reference;
$size = $this->getOriginalSize( $image, $reference );
if ( is_wp_error( $size ) )
return $size;
return $this->getQuality( $config, $size );
}
/**
* Returns the quality set for the current image size.
* If
* @param array $config
* @param int $size
*/
protected function getQuality( Array $config, $size )
{
$result = version_compare( $config[\'breakpoint\'], $size );
return (
0 === $result
AND in_array( $config[\'limit\'], array( \'>\', \'gt\', \'>=\', \'ge\', \'==\', \'=\', \'eq\' ) )
||
1 === $result
AND in_array( $config[\'limit\'], array( \'<\', \'lt\', \'<=\', \'le\', ) )
)
? $config[\'high\']
: $config[\'low\'];
}
/**
* Returns the reference size (width or height).
*
* @param array $config
* @return string|\\WP_Error
*/
protected function getReference( Array $config )
{
$r = $config[\'reference\'];
return ! in_array( $r, array( \'w\', \'h\', ) )
? new \\WP_Error(
\'wrong-arg\',
sprintf( \'Wrong argument for "reference" in %s\', __METHOD__ )
)
: $r;
}
/**
* Returns the size of the original image (width or height)
* depending on the reference.
*
* @param string $image
* @param string $reference
* @return int|\\WP_Error
*/
protected function getOriginalSize( $image, $reference )
{
$size = \'h\' === $reference
? imagesy( $image )
: imagesx( $image );
# @TODO Maybe check is_resource() to see if we got an image
# @TODO Maybe check get_resource_type() for a valid image
# @link http://www.php.net/manual/en/resource.php
return ! $size
? new \\WP_Error(
\'image-failure\',
sprintf( \'Resource failed in %s\', get_class( $this ) )
)
: $size;
}
}