Skip to content
Closed
191 changes: 91 additions & 100 deletions lib/class-wp-rest-image-editor-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class WP_REST_Image_Editor_Controller extends WP_REST_Controller {
*/
public function __construct() {
$this->namespace = '__experimental';
$this->rest_base = '/richimage/(?P<media_id>[\d]+)';
$this->rest_base = '/image-editor/(?P<media_id>[\d]+)';
$this->editor = new Image_Editor();
}

Expand All @@ -42,75 +42,88 @@ public function __construct() {
public function register_routes() {
register_rest_route(
$this->namespace,
$this->rest_base . '/rotate',
$this->rest_base,
array(
array(
'methods' => WP_REST_Server::EDITABLE,
'callback' => array( $this, 'rotate_image' ),
'callback' => array( $this, 'apply_edits' ),
'permission_callback' => array( $this, 'permission_callback' ),
'args' => array(
'angle' => array(
'description' => __( 'Rotation angle', 'gutenberg' ),
'type' => 'integer',
'required' => true,
),
),
),
)
);

register_rest_route(
$this->namespace,
$this->rest_base . '/flip',
array(
array(
'methods' => WP_REST_Server::EDITABLE,
'callback' => array( $this, 'flip_image' ),
'permission_callback' => array( $this, 'permission_callback' ),
'args' => array(
'direction' => array(
'description' => __( 'Flip direction', 'gutenberg' ),
'type' => 'string',
'enum' => array( 'vertical', 'horizontal' ),
'required' => true,
),
),
),
)
);

register_rest_route(
$this->namespace,
$this->rest_base . '/crop',
array(
array(
'methods' => WP_REST_Server::EDITABLE,
'callback' => array( $this, 'crop_image' ),
'permission_callback' => array( $this, 'permission_callback' ),
'args' => array(
'crop_x' => array(
'description' => __( 'Crop offset percentage from left', 'gutenberg' ),
'type' => 'number',
'minimum' => 0,
'required' => true,
),
'crop_y' => array(
'description' => __( 'Crop offset percentage from top', 'gutenberg' ),
'type' => 'number',
'minimum' => 0,
'required' => true,
),
'crop_width' => array(
'description' => __( 'Crop width percentage', 'gutenberg' ),
'type' => 'number',
'minimum' => 1,
'required' => true,
),
'crop_height' => array(
'description' => __( 'Crop height percentage', 'gutenberg' ),
'type' => 'number',
'minimum' => 1,
'required' => true,
array(
'modifiers' => array(
'type' => 'array',
'required' => true,
'items' => array(
'anyOf' => array(
array(
'type' => 'object',
'properties' => array(
'modifier' => array(
'type' => 'string',
'required' => true,
'const' => 'crop',
),
'left' => array(
'type' => 'number',
'required' => true,
'minimum' => 0,
'maximum' => 100,
),
'top' => array(
'type' => 'number',
'required' => true,
'minimum' => 0,
'maximum' => 100,
),
'width' => array(
'type' => 'number',
'required' => true,
'minimum' => 1,
'maximum' => 100,
),
'height' => array(
'type' => 'number',
'required' => true,
'minimum' => 1,
'maximum' => 100,
),
),
),
array(
'type' => 'object',
'properties' => array(
'modifier' => array(
'type' => 'string',
'required' => true,
'const' => 'rotate',
),
'angle' => array(
'type' => 'integer',
'required' => true,
),
),
),
array(
'type' => 'object',
'properties' => array(
'modifier' => array(
'type' => 'string',
'required' => true,
'const' => 'flip',
),
'horizontal' => array(
'type' => 'boolean',
'required' => true,
),
'vertical' => array(
'type' => 'boolean',
'required' => true,
),
),
),
),
),
),
),
),
),
Expand All @@ -136,47 +149,25 @@ public function permission_callback( $request ) {
}

/**
* Rotates an image.
*
* @since 7.x ?
* @access public
*
* @param WP_REST_Request $request Full details about the request.
* @return array|WP_Error If successful image JSON for the modified image, otherwise a WP_Error.
*/
public function rotate_image( $request ) {
$modifier = new Image_Editor_Rotate( $request['angle'] );

return $this->editor->modify_image( $request['media_id'], $modifier );
}

/**
* Flips/mirrors an image.
* Applies all edits in one go.
*
* @since 7.x ?
* @access public
*
* @param WP_REST_Request $request Full details about the request.
* @return array|WP_Error If successful image JSON for the modified image, otherwise a WP_Error.
*/
public function flip_image( $request ) {
$modifier = new Image_Editor_Flip( $request['direction'] );

return $this->editor->modify_image( $request['media_id'], $modifier );
}

/**
* Crops an image.
*
* @since 7.x ?
* @access public
*
* @param WP_REST_Request $request Full details about the request.
* @return array|WP_Error If successful image JSON for the modified image, otherwise a WP_Error.
*/
public function crop_image( $request ) {
$modifier = new Image_Editor_Crop( $request['crop_x'], $request['crop_y'], $request['crop_width'], $request['crop_height'] );

return $this->editor->modify_image( $request['media_id'], $modifier );
public function apply_edits( $request ) {
$modifiers = array();
foreach ( $request['modifiers'] as $modifier ) {
if ( 'rotate' === $modifier['modifier'] ) {
$modifiers[] = new Image_Editor_Rotate( $modifier['angle'] );
} elseif ( 'flip' === $modifier['modifier'] ) {
$modifiers[] = new Image_Editor_Flip( $modifier['vertical'], $modifier['horizontal'] );
} elseif ( 'crop' === $modifier['modifier'] ) {
$modifiers[] = new Image_Editor_Crop( $modifier['left'], $modifier['top'], $modifier['width'], $modifier['height'] );
}
}
return $this->editor->modify_image( $request['media_id'], $modifiers );
}
}
31 changes: 18 additions & 13 deletions lib/image-editor/class-image-editor-crop.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
* @since 7.x ?
*/

/**
* Image editor modifier abstract class.
*/
require_once __DIR__ . '/class-image-editor-modifier.php';

/**
* Crop image modifier.
*/
Expand All @@ -16,14 +21,14 @@ class Image_Editor_Crop extends Image_Editor_Modifier {
*
* @var float
*/
private $crop_x = 0;
private $left = 0;

/**
* Distance from the top for the crop.
*
* @var float
*/
private $crop_y = 0;
private $top = 0;

/**
* Width of the crop.
Expand All @@ -44,14 +49,14 @@ class Image_Editor_Crop extends Image_Editor_Modifier {
*
* Will populate object properties from the provided arguments.
*
* @param float $crop_x Percentage from the left for the crop.
* @param float $crop_y Percentage from the top for the crop.
* @param float $left Percentage from the left for the crop.
* @param float $top Percentage from the top for the crop.
* @param float $width Percentage width for the crop.
* @param float $height Percentage height for the crop.
*/
public function __construct( $crop_x, $crop_y, $width, $height ) {
$this->crop_x = floatval( $crop_x );
$this->crop_y = floatval( $crop_y );
public function __construct( $left, $top, $width, $height ) {
$this->left = floatval( $left );
$this->top = floatval( $top );
$this->width = floatval( $width );
$this->height = floatval( $height );
}
Expand All @@ -65,8 +70,8 @@ public function __construct( $crop_x, $crop_y, $width, $height ) {
* @return array Updated metadata.
*/
public function apply_to_meta( $meta ) {
$meta['crop_x'] = $this->crop_x;
$meta['crop_y'] = $this->crop_y;
$meta['crop_left'] = $this->left;
$meta['crop_top'] = $this->top;
$meta['crop_width'] = $this->width;
$meta['crop_height'] = $this->height;

Expand All @@ -84,12 +89,12 @@ public function apply_to_meta( $meta ) {
public function apply_to_image( $image ) {
$size = $image->get_size();

$crop_x = round( ( $size['width'] * $this->crop_x ) / 100.0 );
$crop_y = round( ( $size['height'] * $this->crop_y ) / 100.0 );
$left = round( ( $size['width'] * $this->left ) / 100.0 );
$top = round( ( $size['height'] * $this->top ) / 100.0 );
$width = round( ( $size['width'] * $this->width ) / 100.0 );
$height = round( ( $size['height'] * $this->height ) / 100.0 );

return $image->crop( $crop_x, $crop_y, $width, $height );
return $image->crop( $left, $top, $width, $height );
}

/**
Expand All @@ -102,7 +107,7 @@ public function apply_to_image( $image ) {
*/
public static function get_filename( $meta ) {
if ( isset( $meta['crop_width'] ) && $meta['crop_width'] > 0 ) {
$target_file = sprintf( 'crop-%d-%d-%d-%d', round( $meta['crop_x'], 2 ), round( $meta['crop_y'], 2 ), round( $meta['crop_width'], 2 ), round( $meta['crop_height'], 2 ) );
$target_file = sprintf( 'crop-%d-%d-%d-%d', round( $meta['crop_left'], 2 ), round( $meta['crop_top'], 2 ), round( $meta['crop_width'], 2 ), round( $meta['crop_height'], 2 ) );

// We need to change the original name to include the crop. This way if it's cropped again we won't clash.
$meta['original_name'] = $target_file;
Expand Down
Loading