php 如何找到图像中的主色?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8730661/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 05:22:54  来源:igfitidea点击:

How to find the Dominant color in image?

php

提问by motioz

i want to find the dominant color in image, how can i do it ?

我想找到图像中的主色,我该怎么做?

it would be great if i can get this in HEX code (exm: #eeeeee)

如果我能在十六进制代码中得到这个就太好了(exm:#eeeeee)

采纳答案by tkone

To find the most "dominant" color in an image, meaning the color that is most prevalent in the image: you'd need to create a histogram of the image.

要找到图像中最“主要”的颜色,即图像中最普遍的颜色:您需要创建图像的直方图。

Here is an the code from this article on how to create a histogram in PHP. (Website has gone off line several times)

这是本文中有关如何在 PHP 中创建直方图的代码。(网站已多次下线)

<?php
$source_file = "test_image.jpg";

// histogram options

$maxheight = 300;
$barwidth = 2;

$im = ImageCreateFromJpeg($source_file);

$imgw = imagesx($im);
$imgh = imagesy($im);

// n = total number or pixels

$n = $imgw*$imgh;

$histo = array();

for ($i=0; $i<$imgw; $i++)
{
        for ($j=0; $j<$imgh; $j++)
        {

                // get the rgb value for current pixel

                $rgb = ImageColorAt($im, $i, $j);

                // extract each value for r, g, b

                $r = ($rgb >> 16) & 0xFF;
                $g = ($rgb >> 8) & 0xFF;
                $b = $rgb & 0xFF;

                // get the Value from the RGB value

                $V = round(($r + $g + $b) / 3);

                // add the point to the histogram

                $histo[$V] += $V / $n;

        }
}

// find the maximum in the histogram in order to display a normated graph

$max = 0;
for ($i=0; $i<255; $i++)
{
        if ($histo[$i] > $max)
        {
                $max = $histo[$i];
        }
}

echo "<div style='width: ".(256*$barwidth)."px; border: 1px solid'>";
for ($i=0; $i<255; $i++)
{
        $val += $histo[$i];

        $h = ( $histo[$i]/$max )*$maxheight;

        echo "<img src=\"img.gif\" width=\"".$barwidth."\"
height=\"".$h."\" border=\"0\">";
}
echo "</div>";
?> 

In that example $maxis your most "dominant" color.

在那个例子中$max是你最“主导”的颜色。

回答by Zachary Schuessler

There is a PHP class developed that handles this, named color extract. However, know that doing this on the server side will require substantial system resources. You may wish to instead do this with canvas.

开发了一个 PHP 类来处理这个问题,名为color extract。但是,要知道在服务器端执行此操作将需要大量系统资源。您可能希望使用canvas来执行此操作。

回答by user2091347

Try this: http://www.coolphptools.com/color_extract.

试试这个:http: //www.coolphptools.com/color_extract

The Image Color Extract PHP class pulls the most common colors (in percentages) out of an image file. The color values are in hexadecimal.

Image Color Extract PHP 类从图像文件中提取最常见的颜色(以百分比表示)。颜色值是十六进制的。

回答by Shahroq

In regard to tkone answer, the $max is just a parameter showing density of the color at an image. I would change the code a bit to return the HEX color:

关于 tkone 答案,$max 只是显示图像颜色密度的参数。我会稍微更改代码以返回十六进制颜色:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Empty Document</title>
</head>

<body>
<?php

error_reporting(0);
function rgb2hex($rgb) {
   $hex = "#";
   $hex .= str_pad(dechex($rgb[0]), 2, "0", STR_PAD_LEFT);
   $hex .= str_pad(dechex($rgb[1]), 2, "0", STR_PAD_LEFT);
   $hex .= str_pad(dechex($rgb[2]), 2, "0", STR_PAD_LEFT);

   return $hex; // returns the hex value including the number sign (#)
}


$source_file = "image.jpg";

// histogram options

$maxheight = 300;
$barwidth = 2;

$im = ImageCreateFromJpeg($source_file);

$imgw = imagesx($im);
$imgh = imagesy($im);

// n = total number or pixels

$n = $imgw*$imgh;

$histo = array();

for ($i=0; $i<$imgw; $i++)
{
        for ($j=0; $j<$imgh; $j++)
        {

                // get the rgb value for current pixel

                $rgb = ImageColorAt($im, $i, $j);
                //echo $rgb."<br>";
                // extract each value for r, g, b

                $r = ($rgb >> 16) & 0xFF;
                $g = ($rgb >> 8) & 0xFF;
                $b = $rgb & 0xFF;

                // get the Value from the RGB value

                $V = round(($r + $g + $b) / 3);
                //echo $V."<br>";
                // add the point to the histogram

                $histo[$V] += $V / $n;
                $histo_color[$V] = rgb2hex([$r,$g,$b]);

        }
}

// find the maximum in the histogram in order to display a normated graph

$max = 0;
for ($i=0; $i<255; $i++)
{
        if ($histo[$i] > $max)
        {
                $max = $histo[$i];
        }
}

echo "<div style='width: ".(256*$barwidth)."px; border: 1px solid'>";
for ($i=0; $i<255; $i++)
{
        $val += $histo[$i];

        $h = ( $histo[$i]/$max )*$maxheight;

        echo "<img src=\"img.gif\" width=\"".$barwidth."\"
height=\"".$h."\" border=\"0\">";
}
echo "</div>";

$key = array_search ($max, $histo);
$col = $histo_color[$key];
?> 

<p style="min-width:100px; min-height:100px; background-color:<?php echo $col?>;"></p>
<img src="<?php echo $source_file?>">
</body>
</html>

Also, it is worth mentioning that this is just the most 'repeated' color at the image that cannot absolutely considered 'dominant' color.

此外,值得一提的是,这只是图像中最“重复”的颜色,不能绝对视为“主导”颜色。

回答by Adam F

Sounds like a delightful code to write! I made a function awhile back that goes through every pixel and adds a shade to each one. What you could do is:

听起来像一个令人愉快的代码编写!不久前我做了一个函数,它遍历每个像素并为每个像素添加阴影。你可以做的是:

For Each Pixel, find the highest color (r,g,or b) and do the math ($colorG++ or something)

对于每个像素,找到最高的颜色(r、g 或 b)并进行数学运算($colorG++ 或其他)

at the end, find out what one is the largest, and there would be your highest rgb shade.

最后,找出最大的那个,然后就会有最高的 rgb 阴影。

I wonder what color would come out if you used the resulting rgb value...

我想知道如果您使用生成的 rgb 值会出现什么颜色...

回答by adilbo

PHP Simple Color Thief

PHP简单的颜色小偷

Detect the Dominant Color used in an Image

检测图像中使用的主色

How it Works

这个怎么运作

PHP:

PHP:

require 'color.php';
$image = 'https://cdn.pixabay.com/photo/2012/11/24/07/43/colorful-67134_960_720.jpg'
$default_color = 'ffffff';
echo simple_color_thief($image, $default_color);

Will return the Hex Color: e0a654

将返回十六进制颜色:e0a654

The color.phpFile:

color.php文件:

/*
PHP Simple Color Thief
======================
Detect the Dominant Color used in an Image
Copyright 2019 Igor Gaffling
*/

function simple_color_thief($img, $default='eee') {
  if(@exif_imagetype($img)) { // CHECK IF IT IS AN IMAGE
    $type = getimagesize($img)[2]; // GET TYPE
    if ($type === 1) { // GIF
      $image = imagecreatefromgif($img);
      // IF IMAGE IS TRANSPARENT (alpha=127) RETURN fff FOR WHITE
      if (imagecolorsforindex($image, imagecolorstotal($image)-1)['alpha'] == 127) return 'fff';
    } else if ($type === 2) { // JPG
      $image = imagecreatefromjpeg($img);
    } else if ($type === 3) { // PNG
      $image = imagecreatefrompng($img);
      // IF IMAGE IS TRANSPARENT (alpha=127) RETURN fff FOR WHITE
      if ((imagecolorat($image, 0, 0) >> 24) & 0x7F === 127) return 'fff';
    } else { // NO CORRECT IMAGE TYPE (GIF, JPG or PNG)
      return $default;
    }
  } else { // NOT AN IMAGE
    return $default;
  }
  $newImg = imagecreatetruecolor(1, 1); // FIND DOMINANT COLOR
  imagecopyresampled($newImg, $image, 0,0,0,0,1,1, imagesx($image), imagesy($image));
  return dechex(imagecolorat($newImg, 0, 0)); // RETURN HEX COLOR
}
// DEMO
foreach(glob('./*.{jpg,png,gif}', GLOB_BRACE) as $i) {
  echo '<div style="width:26%;padding:50px;background:#'.
  simple_color_thief($i,'f00').
  ';display:inline-block"><img style="height:200px" src="'.
  $i.'"></div>';
}

Source: https://github.com/gaffling/PHP-Simple-Color-Thief/

来源:https: //github.com/gaffling/PHP-Simple-Color-Thief/

回答by Pierre MIchel Agbla

You give an image ressouce as argument.

你给出一个图像资源作为参数。

Ex:

前任:

$im=imagecreatefromjpeg("path/to/image");
getDominantcolor($im);

NB: This function will little bit slow down your page since it will compare each color of the image to all other color to make the statistic. It returns rgb value of the dominant color as array

注意:此功能会稍微减慢您的页面速度,因为它会将图像的每种颜色与所有其他颜色进行比较以进行统计。它将主色的 rgb 值作为数组返回

function getDominantcolor($im){

        $width=imagesx($im);
        $height=imagesy($im);
        $colorArr=[];
        $comparArr=[];
        $colCount=0;

        //fixed height
        for ($j=0; $j < $height; $j++) { 
            //fetching color on widths
            for ($i=0; $i < $height; $i++) { 
                $colorArr[]=imagecolorat ( $im ,$i ,$j );
            }

        }


        //fixed height
        for ($col=0; $col < count($colorArr); $col++) { 
            for ($cel=0; $cel <  count($colorArr); $cel++) { 
                if($colorArr[$col]===$colorArr[$cel]){
                    $colCount+=1;
                }
            }
            $comparArr[]=$colCount;
            $colCount=0;
        }


        foreach ($comparArr as $key => $value) {
            if($value===max($comparArr)){
                $max_index=$key;
                break;
            }
        }
        $rgb=$colorArr[$max_index];
        $r = ($rgb >> 16) & 0xFF;
        $g = ($rgb >> 8) & 0xFF;
        $b = $rgb & 0xFF;
        return ['r'=>$r,'g'=>$g,'b'=>$b];

    }

回答by afaf12

You should have a look at GD and Image Functions.

你应该看看GD 和 Image Functions

There is a similar questionon SO about extracting color information from an image with PHP, and it links to this classon github.

还有一个类似的问题关于用PHP从图像中提取颜色信息,SO,并将其链接到这一GitHub上。

回答by Ajeet Lakhani

Though its in javascript but color-thiefis best for getting dominant color in image.

虽然它在 javascript 中,但颜色窃贼最适合在图像中获取主色。

https://github.com/lokesh/color-thief

https://github.com/lokesh/color-thief