Lưu ý trả trước: Câu trả lời dưới đây chưa kết thúc và chưa được kiểm tra, nhưng tôi không còn đủ thời gian, vì vậy tôi sẽ để nó ở đây như bản nháp. Những gì có lẽ cần một đôi mắt thứ hai là phương pháp chất lượng và giải thích version_compare()
.
Đầu tiên chúng ta cần một điểm vào. Sau khi đọc lại bài đăng một lần nữa, tôi nghĩ tốt nhất nên nhảy vào trước khi Trình chỉnh sửa hình ảnh lưu hình ảnh vừa tạo. Vì vậy, đây là một bộ điều khiển vi mô chặn trong quá trình gọi lại được nối image_editor_save_pre
và tải một lớp sau đó đi qua các cài đặt của bạn được xác định bên trong một cuộc gọi lại wpse_jpeg_quality
. Nó chỉ đơn giản trả về các tỷ lệ nén khác nhau cho jpeg_quality
bộ lọc chạy bên trong Trình chỉnh sửa hình ảnh.
<?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;
}
Công nhân thực tế là JPEGQualityWorker
lớp học. Nó nằm trong cùng thư mục với tệp plugin chính ở trên và được đặt tên worker.php
(hoặc bạn thay đổi bộ điều khiển ở trên).
Nó lấy hình ảnh và cài đặt của bạn và sau đó thêm các cuộc gọi lại vào jpeg_quality
bộ lọc. Những gì đang làm là
- lấy tham chiếu hình ảnh của bạn (chiều rộng hoặc chiều cao)
- đặt câu hỏi về điểm dừng của bạn để quyết định nơi chuyển đổi giữa tỷ lệ nén / chất lượng thấp và chất lượng cao
- lấy kích thước hình ảnh gốc
- quyết định chất lượng để trả lại
Điểm dừng và giới hạn là những gì quyết định giữa cao và thấp và như đã đề cập ở trên, điều này có thể cần thêm một số tình yêu.
<?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;
}
}
WP_Image_Editor
" là một giải pháp nhiều hơn những gì tôi đã viết.