PHPerKaigi 2024

Imagick::getImageColors

(PECL imagick 2, PECL imagick 3)

Imagick::getImageColorsGets the number of unique colors in the image

说明

public Imagick::getImageColors(): int

Gets the number of unique colors in the image.

参数

此函数没有参数。

返回值

Returns an int, the number of unique colors in the image.

add a note

User Contributed Notes 2 notes

up
3
holdoffhunger at gmail dot com
11 years ago
I've had difficulty getting this function to return the number of unique colors. Also, I wanted to be able to have an array with each $key value being the RGB of the pixel, and each $value value being the number of times that pixel occurs. Basically, a frequency list. For example, you would have "1 / 0 / 0" for red as a $key value, and "25" for the number of times that pixel color was in the image. So, I wrote some code to do that, using a combination of readImageFile, getImageWidth, getImageHeight, getImagePixelColor, and a simple x/y parser, like so :

<?php

// Test File
// ---------------------------------------------

// Note: This file was just a picture of a 5x5 red square
// inside of a gigantic 521x512 black square, and
// then I did a bunch of random, yellow zigzags.

$file_to_grab_with_location = "test.bmp";

$imagick_type = new Imagick();

// Open File
// ---------------------------------------------

$file_handle_for_viewing_image_file = fopen($file_to_grab_with_location, 'a+');
$imagick_type->readImageFile($file_handle_for_viewing_image_file);

// Preset Information
// ---------------------------------------------

$frequency_list_of_values = array();

// Parse Pixels
// ---------------------------------------------

$image_resolution_width = $imagick_type->getImageWidth();
$image_resolution_height = $imagick_type->getImageHeight();

print(
"Image Resolution: Width - $image_resolution_width / Height - $image_resolution_height<br><br>");

// Parse Image Top-to-Bottom (Y-Variable)
// ---------------------------------------------

for($y = 0; $y < $image_resolution_height; $y++)
{
// Parse Image Left-to-Right (X-Variable)
// ---------------------------------------------

for($x = 0; $x < $image_resolution_width; $x++)
{

// Image Pixel Color
// ---------------------------------------------

$pixel_to_examine = $imagick_type->getImagePixelColor($x,$y);

$pixel_to_examine_color_value_red = $pixel_to_examine->getColorValue(imagick::COLOR_RED);
$pixel_to_examine_color_value_green = $pixel_to_examine->getColorValue(imagick::COLOR_GREEN);
$pixel_to_examine_color_value_blue = $pixel_to_examine->getColorValue(imagick::COLOR_BLUE);

// Set Key Value
// ---------------------------------------------

$key_value = $pixel_to_examine_color_value_red . " / " .
$pixel_to_examine_color_value_green . " / " .
$pixel_to_examine_color_value_blue ;

// Increment Array Entry for Color
// ---------------------------------------------

if(isset($frequency_list_of_values[$key_value]) == TRUE)
{
$temp = $frequency_list_of_values[$key_value];
$temp++;
$frequency_list_of_values[$key_value] = $temp;
}
else
{
$frequency_list_of_values[$key_value] = 1;
}
}
}

// Print Out Array of Values
// ---------------------------------------------

print("<pre>");
print_r($frequency_list_of_values);
print(
"</pre>");

/*

Results:
------------------

Image Resolution: Width - 521 / Height - 512

Array
(
[1 / 0 / 0] => 25
[0 / 0 / 1] => 264107
[1 / 1 / 0] => 2620
)

*/

?>
up
-4
amaral dot regis at hotmail dot com
5 years ago
O exemplo anterior apresentou números fracionados nas chaves da variável $frequency_list_of_values:

Array
(
[1 / 0 / 1] => 157295
[0.83529411764706 / 0.87843137254902 / 0.82352941176471] => 1
[0.80392156862745 / 0.84705882352941 / 0.7843137254902] => 2
[0.8156862745098 / 0.84705882352941 / 0.78823529411765] => 1
...

Então eu fiz uma alteração que melhora o resultado para quem esta buscando saber quais as cores dominantes na imagem, mostrando a chave com o valor rgb exato:
<?php

$file_to_grab_with_location
= $imagepath; //caminho relativo ao arquivo de imagem

$imagick_type = new \Imagick();

$file_handle_for_viewing_image_file = fopen($file_to_grab_with_location, 'a+');
$imagick_type->readImageFile($file_handle_for_viewing_image_file);

$frequency_list_of_values = array();

$image_resolution_width = $imagick_type->getImageWidth();
$image_resolution_height = $imagick_type->getImageHeight();

print(
"Image Resolution: Width - $image_resolution_width / Height - $image_resolution_height<br><br>");

for(
$y = 0; $y < $image_resolution_height; $y++)
{

for(
$x = 0; $x < $image_resolution_width; $x++)
{

$pixel_to_examine = $imagick_type->getImagePixelColor($x,$y);

if(isset(
$frequency_list_of_values[$pixel_to_examine->getColorAsString()]) == TRUE)
{
$temp = $frequency_list_of_values[$pixel_to_examine->getColorAsString()];
$temp++;
$frequency_list_of_values[$pixel_to_examine->getColorAsString()] = $temp;
}
else
{
$frequency_list_of_values[$pixel_to_examine->getColorAsString()] = 1;
}
}

arsort($frequency_list_of_values);
}

print(
"<pre>");
print_r($frequency_list_of_values);
print(
"</pre>");

?>

Resultado:
Image Resolution: Width - 1965 / Height - 998

Array
(
[srgba(255,0,255,0)] => 451654
[srgb(54,52,53)] => 281069
[srgb(177,51,54)] => 130449
[srgb(236,50,55)] => 64001
...

O método é demorado para imagens muito grandes, pois ele analisa pixel a pixel.
To Top