Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@
class Dominant_Color_Image_Editor_GD extends WP_Image_Editor_GD {

/**
* Get dominant color from a file.
* Get dominant color from a file as raw RGB values.
*
* @since 1.0.0
*
* @return string|WP_Error Dominant hex color string, or an error on failure.
* @return array{r: int, g: int, b: int}|WP_Error RGB values (0-255), or WP_Error on failure.
*/
public function get_dominant_color() {

Expand All @@ -49,15 +49,12 @@ public function get_dominant_color() {
if ( false === $rgb ) {
return new WP_Error( 'image_editor_dominant_color_error', __( 'Dominant color detection failed.', 'dominant-color-images' ) );
}
$r = ( $rgb >> 16 ) & 0xFF;
$g = ( $rgb >> 8 ) & 0xFF;
$b = $rgb & 0xFF;
$hex = dominant_color_rgb_to_hex( $r, $g, $b );
if ( null === $hex ) {
return new WP_Error( 'image_editor_dominant_color_error', __( 'Dominant color detection failed.', 'dominant-color-images' ) );
}

return $hex;
return array(
'r' => ( $rgb >> 16 ) & 0xFF,
'g' => ( $rgb >> 8 ) & 0xFF,
'b' => $rgb & 0xFF,
);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@
class Dominant_Color_Image_Editor_Imagick extends WP_Image_Editor_Imagick {

/**
* Get dominant color from a file.
* Get dominant color from a file as raw RGB values.
*
* @since 1.0.0
*
* @return string|WP_Error Dominant hex color string, or an error on failure.
* @return array{r: int, g: int, b: int}|WP_Error RGB values (0-255), or WP_Error on failure.
*/
public function get_dominant_color() {

Expand All @@ -38,12 +38,12 @@ public function get_dominant_color() {
$this->image->resizeImage( 1, 1, Imagick::FILTER_LANCZOS, 1 );
$pixel = $this->image->getImagePixelColor( 0, 0 );
$color = $pixel->getColor();
$hex = dominant_color_rgb_to_hex( $color['r'], $color['g'], $color['b'] );
if ( null === $hex ) {
return new WP_Error( 'image_editor_dominant_color_error', __( 'Dominant color detection failed.', 'dominant-color-images' ) );
}

return $hex;
return array(
'r' => $color['r'],
'g' => $color['g'],
'b' => $color['b'],
);
} catch ( Exception $e ) {
/* translators: %s is the error message. */
return new WP_Error( 'image_editor_dominant_color_error', sprintf( __( 'Dominant color detection failed: %s', 'dominant-color-images' ), $e->getMessage() ) );
Expand Down
67 changes: 39 additions & 28 deletions plugins/dominant-color-images/helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,9 @@ function dominant_color_get_dominant_color_data( int $attachment_id ) {
}

$file = dominant_color_get_attachment_file_path( $attachment_id );
if ( false === $file ) {
$file = get_attached_file( $attachment_id );
}
if ( false === $file ) {
return new WP_Error( 'no_image_found', __( 'Unable to load image.', 'dominant-color-images' ) );
}
add_filter( 'wp_image_editors', 'dominant_color_set_image_editors' );

/**
* Editor.
Expand All @@ -113,7 +109,6 @@ function dominant_color_get_dominant_color_data( int $attachment_id ) {
),
)
);
remove_filter( 'wp_image_editors', 'dominant_color_set_image_editors' );

if ( is_wp_error( $editor ) ) {
return $editor;
Expand All @@ -135,11 +130,41 @@ function dominant_color_get_dominant_color_data( int $attachment_id ) {
if ( is_wp_error( $dominant_color ) ) {
return $dominant_color;
}
$dominant_color_data['dominant_color'] = $dominant_color;

$hex = dominant_color_rgb_to_hex( $dominant_color['r'], $dominant_color['g'], $dominant_color['b'] );
if ( null === $hex ) {
return new WP_Error(
'image_editor_dominant_color_error',
__( 'Dominant color detection failed.', 'dominant-color-images' )
);
}
$dominant_color_data['dominant_color'] = $hex;

return $dominant_color_data;
}

/**
* Retrieves attachment metadata for an image attachment.
*
* @since 1.0.0
*
* @param int $attachment_id Attachment ID.
* @return array<string, mixed>|null Attachment metadata array, or null if not an image or metadata unavailable.
*/
function dominant_color_get_attachment_metadata( int $attachment_id ): ?array {

if ( ! wp_attachment_is_image( $attachment_id ) ) {
return null;
}

$image_meta = wp_get_attachment_metadata( $attachment_id );
if ( ! is_array( $image_meta ) ) {
return null;
}

return $image_meta;
}

/**
* Gets file path of image based on size.
*
Expand All @@ -150,21 +175,17 @@ function dominant_color_get_dominant_color_data( int $attachment_id ) {
* @return false|string Path to an image or false if not found.
*/
function dominant_color_get_attachment_file_path( int $attachment_id, string $size = 'medium' ) {
$imagedata = wp_get_attachment_metadata( $attachment_id );
if ( ! is_array( $imagedata ) ) {
return false;
}

if ( ! isset( $imagedata['sizes'][ $size ] ) ) {
$filepath = get_attached_file( $attachment_id );
if ( false === $filepath ) {
return false;
}

$file = get_attached_file( $attachment_id );
if ( false === $file ) {
return false;
}
$image_meta = dominant_color_get_attachment_metadata( $attachment_id );

$filepath = str_replace( wp_basename( $file ), $imagedata['sizes'][ $size ]['file'], $file );
if ( isset( $image_meta['sizes'][ $size ] ) ) {
$filepath = str_replace( wp_basename( $filepath ), $image_meta['sizes'][ $size ]['file'], $filepath );
}

return $filepath;
}
Expand All @@ -178,13 +199,7 @@ function dominant_color_get_attachment_file_path( int $attachment_id, string $si
* @return string|null Hex value of dominant color or null if not set.
*/
function dominant_color_get_dominant_color( int $attachment_id ): ?string {
if ( ! wp_attachment_is_image( $attachment_id ) ) {
return null;
}
$image_meta = wp_get_attachment_metadata( $attachment_id );
if ( ! is_array( $image_meta ) ) {
return null;
}
$image_meta = dominant_color_get_attachment_metadata( $attachment_id );

if ( ! isset( $image_meta['dominant_color'] ) ) {
return null;
Expand All @@ -202,10 +217,7 @@ function dominant_color_get_dominant_color( int $attachment_id ): ?string {
* @return bool|null Whether the image has transparency, or null if not set.
*/
function dominant_color_has_transparency( int $attachment_id ): ?bool {
$image_meta = wp_get_attachment_metadata( $attachment_id );
if ( ! is_array( $image_meta ) ) {
return null;
}
$image_meta = dominant_color_get_attachment_metadata( $attachment_id );

if ( ! isset( $image_meta['has_transparency'] ) ) {
return null;
Expand All @@ -214,7 +226,6 @@ function dominant_color_has_transparency( int $attachment_id ): ?bool {
return $image_meta['has_transparency'];
}


/**
* Gets hex color from RGB.
*
Expand Down
2 changes: 2 additions & 0 deletions plugins/dominant-color-images/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,6 @@

require_once __DIR__ . '/helper.php';
require_once __DIR__ . '/hooks.php';

add_filter( 'wp_image_editors', 'dominant_color_set_image_editors', 999, 1 );
// @codeCoverageIgnoreEnd
42 changes: 28 additions & 14 deletions plugins/dominant-color-images/tests/data/class-testcase.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,10 @@ public function provider_get_dominant_color_invalid_images(): array {
public function provider_get_dominant_color_none_images(): array {
return array(
'pdf' => array(
'files_path' => TESTS_PLUGIN_DIR . '/tests/data/images/wordpress-gsoc-flyer.pdf',
'image_path' => TESTS_PLUGIN_DIR . '/tests/data/images/wordpress-gsoc-flyer.pdf',
),
'mp4' => array(
'files_path' => TESTS_PLUGIN_DIR . '/tests/data/images/small-video.mp4',
'image_path' => TESTS_PLUGIN_DIR . '/tests/data/images/small-video.mp4',
),
);
}
Expand All @@ -182,7 +182,6 @@ public function test_get_dominant_color_valid( string $image_path, array $expect
}

$attachment_id = self::factory()->attachment->create_upload_object( $image_path );
wp_maybe_generate_attachment_metadata( get_post( $attachment_id ) );

$dominant_color_data = dominant_color_get_dominant_color_data( $attachment_id );

Expand All @@ -208,47 +207,62 @@ public function test_get_dominant_color_invalid( string $image_path ): void {
if ( ! wp_image_editor_supports( array( 'mime_type' => $mime_type ) ) ) {
$this->markTestSkipped( "Mime type $mime_type is not supported." );
}
$attachment_id = self::factory()->attachment->create_upload_object( $image_path );
wp_maybe_generate_attachment_metadata( get_post( $attachment_id ) );
$attachment_id = self::factory()->attachment->create(
array(
'post_mime_type' => $mime_type,
)
);

$dominant_color_data = dominant_color_get_dominant_color_data( $attachment_id );

$this->assertWPError( $dominant_color_data );
$this->assertStringContainsString( 'unsupported_attachment_type', $dominant_color_data->get_error_code() );
$this->assertSame( 'unsupported_attachment_type', $dominant_color_data->get_error_code() );
}

/**
* Test the function returns a WP_Error object for unsupported mime types.
* Tests dominant_color_get_dominant_color_data() returns a WP_Error when the
* dominant_color_supported_mime_types filter returns an empty array.
*
* @covers dominant_color_get_dominant_color_data
*/
public function test_get_dominant_color_data_unsupported_mime_type(): void {
add_filter( 'dominant_color_supported_mime_types', '__return_empty_array' );
$image_path = TESTS_PLUGIN_DIR . '/tests/data/images/red.jpg';

$attachment_id = self::factory()->attachment->create_upload_object( $image_path );
wp_maybe_generate_attachment_metadata( get_post( $attachment_id ) );
$attachment_id = self::factory()->attachment->create(
array(
'post_mime_type' => 'image/jpeg',
)
);

$dominant_color_data = dominant_color_get_dominant_color_data( $attachment_id );

$this->assertWPError( $dominant_color_data );
$this->assertStringContainsString( 'unsupported_attachment_type', $dominant_color_data->get_error_code() );
$this->assertSame( 'unsupported_attachment_type', $dominant_color_data->get_error_code() );
}

/**
* Test if the function returns the correct color.
* Tests dominant_color_get_dominant_color_data() returns a WP_Error for non-image file types.
*
* @covers Dominant_Color_Image_Editor_GD::get_dominant_color
* @covers Dominant_Color_Image_Editor_Imagick::get_dominant_color
*
* @dataProvider provider_get_dominant_color_none_images
*/
public function test_get_dominant_color_none_images( string $image_path ): void {
$attachment_id = self::factory()->attachment->create_upload_object( $image_path );
wp_maybe_generate_attachment_metadata( get_post( $attachment_id ) );
$mime_type = wp_check_filetype( $image_path )['type'];
if ( false === $mime_type ) {
$this->markTestSkipped( 'Mime type is not supported.' );
}

$attachment_id = self::factory()->attachment->create(
array(
'post_mime_type' => $mime_type,
)
);

$dominant_color_data = dominant_color_get_dominant_color_data( $attachment_id );

$this->assertWPError( $dominant_color_data );
$this->assertSame( 'unsupported_attachment_type', $dominant_color_data->get_error_code() );
}
}
Loading
Loading