Skip to content

Commit

Permalink
fix: resize behaviour for WordPress defined image sizes, preserve cro…
Browse files Browse the repository at this point in the history
…pping for custom sizes

test: adds test for image sizes
  • Loading branch information
selul committed Jan 21, 2019
1 parent b66f135 commit a42f830
Show file tree
Hide file tree
Showing 8 changed files with 310 additions and 131 deletions.
101 changes: 19 additions & 82 deletions inc/image.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,84 +16,6 @@ class Optml_Image {
*/
const SIGNATURE_SIZE = 8;

/**
* Resize the image while keeping aspect ratio to fit given size.
*/
const RESIZE_FILL = 'fill';
/**
* Resize the image while keeping aspect ratio
* to fill given size and cropping projecting parts.
*/
const RESIZE_FIT = 'fit';
/**
* Crops the image to a given size.
*/
const RESIZE_CROP = 'crop';


/**
* Top edge.
*/
const GRAVITY_NORTH = 'no';
/**
* Bottom Edge.
*/
const GRAVITY_SOUTH = 'so';
/**
* Right Edge.
*/
const GRAVITY_EAST = 'ea';
/**
* Left edge.
*/
const GRAVITY_WEST = 'we';

/**
* Top right corner.
*/
const GRAVITY_NORTH_WEST = 'noea';
/**
* Top left corner.
*/
const GRAVITY_NORTH_EAST = 'nowe';
/**
* Bottom right corner.
*/
const GRAVITY_SOUTH_EAST = 'soea';
/**
* Bottom left corner.
*/
const GRAVITY_SOUTH_WEST = 'sowe';


/**
* Center
*/
const GRAVITY_CENTER = 'ce';
/**
* Detects the most "interesting" section of the image and
* considers it as the center of the resulting image
*/
const GRAVITY_SMART = 'sm';
/**
* Detects the most "interesting" section of the image and
* considers it as the center of the resulting image
*/
const GRAVITY_FOCUS_POINT = 'fp';

/**
* Floating point numbers between 0 and 1 that define the coordinates of the resulting image for X axis.
*
* @var int Focus point X.
*/
private $focus_point_x = 0;
/**
* Floating point numbers between 0 and 1 that define the coordinates of the resulting image for X axis.
*
* @var int Focus point Y.
*/
private $focus_point_y = 0;

/**
* Quality of the resulting image.
*
Expand All @@ -118,6 +40,12 @@ class Optml_Image {
* @var Optml_Watermark Watermark.
*/
private $watermark = null;
/**
* Resize type for the image.
*
* @var Optml_Resize Resize details.
*/
private $resize = null;
/**
* Source image url.
*
Expand All @@ -141,10 +69,14 @@ public function __construct( $url = '', $args = array() ) {
$this->width->set( $args['width'] );
$this->height->set( $args['height'] );
$this->quality->set( $args['quality'] );

if ( isset( $args['watermark_id'] ) && $args['watermark_id'] != 0 ) {
$this->watermark->set( $args['watermark_id'] );
}

if ( isset( $args['resize'] ) ) {
$this->resize->set( $args['resize'] );
}
$this->source_url = $url;

}
Expand All @@ -153,10 +85,12 @@ public function __construct( $url = '', $args = array() ) {
* Set defaults for image transformations.
*/
private function set_defaults() {
$this->width = new Optml_Width( 'auto' );
$this->height = new Optml_Height( 'auto' );
$this->quality = new Optml_Quality( 'auto' );
$this->watermark = new Optml_Watermark();
$this->width = new Optml_Width( 'auto' );
$this->height = new Optml_Height( 'auto' );
$this->quality = new Optml_Quality( 'auto' );
$this->watermark = new Optml_Watermark();
$this->resize = new Optml_Resize();

$this->focus_point_x = 0;
$this->focus_point_y = 0;
}
Expand All @@ -179,6 +113,9 @@ public function get_url( $signed = false ) {
if ( $this->quality->get() > 0 || $this->quality->get() === 'eco' ) {
$path_parts[] = $this->quality->toString();
}
if ( ! empty( $this->resize->get() ) ) {
$path_parts[] = $this->resize->toString();
}
if ( is_array( $this->watermark->get() ) && isset( $this->watermark->get()['id'] ) && $this->watermark->get()['id'] != 0 ) {
$path_parts[] = $this->watermark->toString();
}
Expand Down
162 changes: 162 additions & 0 deletions inc/image_properties/resize.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
<?php

/**
* Class Optml_Resize
*/
class Optml_Resize extends Optml_Property_Type {


/**
* Resize the image while keeping aspect ratio to fit given size.
*/
const RESIZE_FILL = 'fill';
/**
* Resize the image while keeping aspect ratio
* to fill given size and cropping projecting parts.
*/
const RESIZE_FIT = 'fit';
/**
* Crops the image to a given size.
*/
const RESIZE_CROP = 'crop';


/**
* Top edge.
*/
const GRAVITY_NORTH = 'no';
/**
* Bottom Edge.
*/
const GRAVITY_SOUTH = 'so';
/**
* Right Edge.
*/
const GRAVITY_EAST = 'ea';
/**
* Left edge.
*/
const GRAVITY_WEST = 'we';

/**
* Top right corner.
*/
const GRAVITY_NORTH_WEST = 'noea';
/**
* Top left corner.
*/
const GRAVITY_NORTH_EAST = 'nowe';
/**
* Bottom right corner.
*/
const GRAVITY_SOUTH_EAST = 'soea';
/**
* Bottom left corner.
*/
const GRAVITY_SOUTH_WEST = 'sowe';


/**
* Center
*/
const GRAVITY_CENTER = 'ce';
/**
* Detects the most "interesting" section of the image and
* considers it as the center of the resulting image
*/
const GRAVITY_SMART = 'sm';
/**
* Detects the most "interesting" section of the image and
* considers it as the center of the resulting image
*/
const GRAVITY_FOCUS_POINT = 'fp';

/**
* Floating point numbers between 0 and 1 that define the coordinates of the resulting image for X axis.
*
* @var int Focus point X.
*/
private $focus_point_x = 0;
/**
* Floating point numbers between 0 and 1 that define the coordinates of the resulting image for X axis.
*
* @var int Focus point Y.
*/
private $focus_point_y = 0;

/**
* Resize type.
*
* @var string Resize type string.
*/
private $resize_type = '';

/**
* Gravity type.
*
* @var string Gravity type string.
*/
private $gravity = '';

/**
* Optml_Resize constructor.
*/
public function __construct( $value = array() ) {
$this->set( $value );
}

/**
* Set property value.
*
* @param mixed $value Value to set.
*/
public function set( $value ) {
$this->resize_type = isset( $value['type'] ) ? $value['type'] : '';
$this->gravity = isset( $value['gravity'] ) ? is_array( $value['gravity'] ) ? self::GRAVITY_FOCUS_POINT : $value['gravity'] : '';
if ( $this->gravity === self::GRAVITY_FOCUS_POINT ) {
$this->focus_point_x = $value['gravity'][0];
$this->focus_point_y = $value['gravity'][1];
}

}

/**
* Return property value.
*
* @return mixed
*/
public function get() {
if ( empty( $this->resize_type ) ) {
return [];
}
if ( empty( $this->gravity ) ) {
return [ 'type' => $this->resize_type ];
}
if ( $this->gravity === self::GRAVITY_FOCUS_POINT ) {
return [ 'type' => $this->gravity, 'gravity' => [ $this->focus_point_x, $this->focus_point_y ] ];
}

return [
'type' => $this->resize_type,
'gravity' => $this->gravity,
];
}

/**
* Return ImageProxy URL formatted string property.
*
* @return string
*/
public function toString() {

$resize = sprintf( 'rt:%s', $this->resize_type );

$resize .= sprintf( '/g:%s', $this->gravity );

if ( $this->gravity === self::GRAVITY_FOCUS_POINT ) {
$resize .= sprintf( ':%s:%s', $this->focus_point_x, $this->focus_point_y );
}

return $resize;
}
}
2 changes: 1 addition & 1 deletion inc/settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class Optml_Settings {
'quality' => 'auto',
'wm_id' => 0,
'wm_opacity' => 1,
'wm_position' => Optml_Image::GRAVITY_CENTER,
'wm_position' => Optml_Resize::GRAVITY_CENTER,
'wm_x' => 0,
'wm_y' => 0,
'wm_scale' => 0,
Expand Down
10 changes: 6 additions & 4 deletions inc/tag_replacer.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public function process_image_tags( $content, $images = array() ) {
$image_sizes = self::image_sizes();
foreach ( $images[0] as $index => $tag ) {
$width = $height = false;
$resize = array( 'resize' => Optml_Image::RESIZE_FIT );
$resize = array( );
$new_tag = $tag;
$src = $tmp = wp_unslash( $images['img_url'][ $index ] );
if ( apply_filters( 'optml_ignore_image_link', false, $src ) ||
Expand Down Expand Up @@ -228,7 +228,6 @@ public function filter_image_downsize( $image, $attachment_id, $size ) {
$sizes = array(
'width' => isset( $image_meta['width'] ) ? intval( $image_meta['width'] ) : 'auto',
'height' => isset( $image_meta['height'] ) ? intval( $image_meta['height'] ) : 'auto',
'resize' => Optml_Image::RESIZE_FIT,
);

// in case there is a custom image size $size will be an array.
Expand All @@ -238,13 +237,16 @@ public function filter_image_downsize( $image, $attachment_id, $size ) {
$sizes['height'] = ( $size[1] < $sizes['height'] ? $size[1] : $sizes['height'] );

} elseif ( 'full' !== $size && isset( $image_args[ $size ] ) ) { // overwrite if there a size

$sizes['width'] = $image_args[ $size ]['width'] < $sizes['width'] ? $image_args[ $size ]['width'] : $sizes['width'];
$sizes['height'] = $image_args[ $size ]['height'] < $sizes['height'] ? $image_args[ $size ]['height'] : $sizes['height'];
$sizes = array_merge( $sizes, $this->to_optml_crop( $image_args[ $size ]['crop'] ) );
$sizes['resize'] = $this->to_optml_crop( $image_args[ $size ]['crop'] );
}

$new_sizes = $this->to_optml_dimensions_bound( $sizes['width'], $sizes['height'], $this->max_width, $this->max_height );

$new_sizes = array_merge( $sizes, $new_sizes );
$image_url = $this->strip_image_size_from_url( $image_url );

$new_url = apply_filters( 'optml_content_url', $image_url, $new_sizes );

if ( $new_url === $image_url ) {
Expand Down
Loading

0 comments on commit a42f830

Please sign in to comment.