使用PHP从图像中获取简化的调色板?

时间:2013-02-25 06:43:27

标签: php image

到目前为止,我已经找到了如何获取图像中每个像素的所有RGB值的示例,但我想要一些能够分解图像并给我一个简化的调色板的东西。

有没有办法使用imagetruecolortopalette以某种方式吐出减少的调色板颜色,或者将图像分成25 x 25块,然后获取该块的平均值?

也许有一种替代方案我不知道?我基本上只是希望能够找到图像中最常见的颜色。

提前致谢。

1 个答案:

答案 0 :(得分:1)

嗯,我已经为客户创造了这样的东西。屏幕截图位于

之下

enter image description here

完整的代码如下

$microTime = microtime(true);


function textColor($R1, $G1, $B1) {

    $a = (($R1 * 299) + ($G1 * 587 ) + ($B1 * 114 )) / 1000;
    if ($a < 128)
        return 'white';
    else
        return 'black';
}

function rgb2html($r, $g = -1, $b = -1) {
    $hex = "#";
    $hex.= str_pad(dechex($r), 2, "0", STR_PAD_LEFT);
    $hex.= str_pad(dechex($g), 2, "0", STR_PAD_LEFT);
    $hex.= str_pad(dechex($b), 2, "0", STR_PAD_LEFT);

    return $hex;

    if (is_array($r) && sizeof($r) == 3)
        list($r, $g, $b) = $r;

    $r = intval($r);
    $g = intval($g);
    $b = intval($b);

    $r = dechex($r < 0 ? 0 : ($r > 255 ? 255 : $r));
    $g = dechex($g < 0 ? 0 : ($g > 255 ? 255 : $g));
    $b = dechex($b < 0 ? 0 : ($b > 255 ? 255 : $b));

    $color = (strlen($r) < 2 ? '0' : '') . $r;
    $color .= (strlen($g) < 2 ? '0' : '') . $g;
    $color .= (strlen($b) < 2 ? '0' : '') . $b;
    return '#' . $color;
}

function colorPalette($imageFile, $colorJump, $granularity = 5) {

    $granularity = max(1, abs((int) $granularity));
    $colors = array();
    $ratio = array();
    $wastageCount = array();
    $occurrenceSCount = array();
    $occurrenceMCount = array();


    $size = @getimagesize($imageFile);



    if ($size === false) {
        return false;
    }
    $img = @imagecreatefromstring(file_get_contents($imageFile));

    if (!$img) {
        user_error("Unable to open image file");
        return false;
    }
    for ($y = 0; $y < $size[1]; $y += $granularity) {
        $lastColor = NULL;
        $lastX = -1;

        for ($x = 0; $x < $size[0]; $x += $granularity) {
            $thisColor = imagecolorat($img, $x, $y);
            $rgb = imagecolorsforindex($img, $thisColor);

            $red = round(round(($rgb['red'] / $colorJump)) * $colorJump);
            $green = round(round(($rgb['green'] / $colorJump)) * $colorJump);
            $blue = round(round(($rgb['blue'] / $colorJump)) * $colorJump);

            $thisRGB = $red . ',' . $green . ',' . $blue;


            if ($lastColor != $thisRGB) {

                if (array_key_exists($thisRGB, $wastageCount)) {
                    $wastageCount[$thisRGB]++;
                } else {
                    $wastageCount[$thisRGB] = 1;
                }

                if ($lastX + 1 == $x) {
                    if (array_key_exists($lastColor, $occurrenceSCount)) {
                        $occurrenceSCount[$lastColor]++;
                    } else {
                        $occurrenceSCount[$lastColor] = 1;
                    }
                }


                if ($lastX + 1 != $x) {
                    if (array_key_exists($lastColor, $occurrenceMCount)) {
                        $occurrenceMCount[$lastColor]++;
                    } else {
                        $occurrenceMCount[$lastColor] = 1;
                    }
                }

                $lastColor = $thisRGB;
                $lastX = $x;
            }


            if (array_key_exists($thisRGB, $colors)) {
                $colors[$thisRGB]++;
            } else {
                $colors[$thisRGB] = 1;
            }
        }
    }

    $totalPixels = array_sum($colors);
    foreach ($colors as $k => $v) {
        $ratio[$k] = round(($v / $totalPixels ) * 100, 2);
    }

    return array($ratio, $wastageCount, $colors, $occurrenceSCount, $occurrenceMCount);
}

使用

    $colorJump = 1;
    $pixelJump = 1;
    $paletteR = colorPalette($dbImgFile_dir, $colorJump, $pixelJump);
    $palette = $paletteR[0];
    $wastage = $paletteR[1];
    $colorsFound = $paletteR[2];
    $occSArray = $paletteR[3];
    $occMArray = $paletteR[4];
    $totalPixels = array_sum($colorsFound);

    $totalTime = abs(microtime(true) - $microTime);
循环变得更复杂,因为我必须从数据库中获取托盘并将颜色与它们匹配,并且还使用了完全自定义代码的模板解析器,并且对您没有帮助。

从这里忽略“必需权重”列,计算单次出现次数和多次出现次数,如果只有一个像素,例如RED, RED, BLUE, RED, RED它将是1次出现和2次多次出现