使用 PHP 检测图像中的主要颜色

2022-08-30 12:14:29

我正在尝试复制 Dribbble.com 在检测图像中的主要颜色时所做的功能。在下图中,您可以看到 Dribbble.com 的屏幕截图,该屏幕截图显示了左侧图像中的8种主要颜色。这是图像中的实际页面 http://dribbble.com/shots/528033-Fresh-Easy?list=following

我需要能够在PHP中做到这一点,一旦我得到我需要的颜色,我就会将它们保存到数据库中,这样就不需要在每次页面加载时运行处理。

在对如何从图像中获取这些颜色进行了一些研究之后,有些人说您只需逐个像素地检查图像,然后保存出现次数最多的颜色即可。其他人说它还有更多,并且获得最常见的颜色不会产生所需的效果。他们说你需要量化图像/颜色(我现在迷路了)。

在下图中,下面的Dribble镜头是一个执行相同操作的Javascript库,该页面可以在此处查看 http://lokeshdhakar.com/projects/color-thief/

查看该页面的源代码,我可以看到有一个名为Javascript的文件,结果非常好。所以我希望能够做Javascript库所做的,但使用PHP和GD / ImageMagick。quantize.js

enter image description here


我发现这个函数将使用PHP在图像中返回颜色和计数,但结果与上面的Javascript版本和Dribble结果不同

/**
 * Returns the colors of the image in an array, ordered in descending order, where the keys are the colors, and the values are the count of the color.
 *
 * @return array
 */
function Get_Color()
{
    if (isset($this->image))
    {
        $PREVIEW_WIDTH    = 150;  //WE HAVE TO RESIZE THE IMAGE, BECAUSE WE ONLY NEED THE MOST SIGNIFICANT COLORS.
        $PREVIEW_HEIGHT   = 150;
        $size = GetImageSize($this->image);
        $scale=1;
        if ($size[0]>0)
        $scale = min($PREVIEW_WIDTH/$size[0], $PREVIEW_HEIGHT/$size[1]);
        if ($scale < 1)
        {
            $width = floor($scale*$size[0]);
            $height = floor($scale*$size[1]);
        }
        else
        {
            $width = $size[0];
            $height = $size[1];
        }
        $image_resized = imagecreatetruecolor($width, $height);
        if ($size[2]==1)
        $image_orig=imagecreatefromgif($this->image);
        if ($size[2]==2)
        $image_orig=imagecreatefromjpeg($this->image);
        if ($size[2]==3)
        $image_orig=imagecreatefrompng($this->image);
        imagecopyresampled($image_resized, $image_orig, 0, 0, 0, 0, $width, $height, $size[0], $size[1]); //WE NEED NEAREST NEIGHBOR RESIZING, BECAUSE IT DOESN'T ALTER THE COLORS
        $im = $image_resized;
        $imgWidth = imagesx($im);
        $imgHeight = imagesy($im);
        for ($y=0; $y < $imgHeight; $y++)
        {
            for ($x=0; $x < $imgWidth; $x++)
            {
                $index = imagecolorat($im,$x,$y);
                $Colors = imagecolorsforindex($im,$index);
                $Colors['red']=intval((($Colors['red'])+15)/32)*32;    //ROUND THE COLORS, TO REDUCE THE NUMBER OF COLORS, SO THE WON'T BE ANY NEARLY DUPLICATE COLORS!
                $Colors['green']=intval((($Colors['green'])+15)/32)*32;
                $Colors['blue']=intval((($Colors['blue'])+15)/32)*32;
                if ($Colors['red']>=256)
                $Colors['red']=240;
                if ($Colors['green']>=256)
                $Colors['green']=240;
                if ($Colors['blue']>=256)
                $Colors['blue']=240;
                $hexarray[]=substr("0".dechex($Colors['red']),-2).substr("0".dechex($Colors['green']),-2).substr("0".dechex($Colors['blue']),-2);
            }
        }
        $hexarray=array_count_values($hexarray);
        natsort($hexarray);
        $hexarray=array_reverse($hexarray,true);
        return $hexarray;

    }
    else die("You must enter a filename! (\$image parameter)");
}

所以我问是否有人知道我如何使用PHP完成这样的任务?可能已经存在您知道的东西或任何提示,让我更接近这样做将不胜感激


答案 1

这正是您在PHP中寻找的内容:https://github.com/thephpleague/color-extractor

例:

use League\ColorExtractor\Palette;

$palette = Palette::fromFilename('some/image.png');

$topEightColors = $palette->getMostUsedColors(8);

答案 2

这是我获得图像主色的简单方法

$image=imagecreatefromjpeg('image.jpg');
$thumb=imagecreatetruecolor(1,1);
imagecopyresampled($thumb,$image,0,0,0,0,1,1,imagesx($image),imagesy($image));
$mainColor=strtoupper(dechex(imagecolorat($thumb,0,0)));
echo $mainColor;

推荐