-2

所以我制作了这个脚本来获取图像中最常用的颜色。问题是,他们用我编码的方式让它变得非常无用。

该脚本只能在小图像上找到颜色。大的会产生这个错误:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 36 bytes)

我将每个像素的十六进制值插入到一个数组中。这就是问题所在,我应该怎么做才能避免使用大型阵列?

剧本:

$im = imagecreatefromjpeg("images/2.jpg");

function common($img) {
    $w = imagesx($img);
    $h = imagesy($img);
    $r = $g = $b = 0;
    $count = 0;

    $array = array();

    for($y = 0; $y < $h; $y++) {
        for($x = 0; $x < $w; $x++) {
            $rgb = imagecolorat($img, $x, $y);
            $r += $rgb >> 16;
            $g += $rgb >> 8 & 255;
            $b += $rgb & 255;
            $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);
            $array[$count++] = $hex;
        }
    }

    $result = array_count_values($array);
    asort($result);
    end($result);
    $answer = key($result);

    return $answer;
}

$common = common($im);
echo $common;
4

2 回答 2

0

一种更节省内存的方法是创建一个包含文档中颜色的数组,并在每次看到它时增加一种颜色。

在伪代码中:

$colors=array();
for(;$i<count($pixels);$i++){
    $pixel=$pixels[$i];
    if(isset($colors[getcolor($pixels[$i])]){
        $colors[getcolor($pixels[$i]++;
    }else{
        $colors[getcolor($pixels[$i]=1;
    }
}

然后获取编号最大的数组元素。

于 2013-09-21T23:44:54.880 回答
0

与其保存数组中的每个像素,为什么不用计数器为每种不同的颜色只插入一个元素呢?就像是:

if ( !isset( $array[$hex] ) )
{
    $array[$hex] = 1;
}
else
{
    $array[$hex]++;
}

这样您就可以在数组中找到具有最高计数的颜色:

$highest_hex = "";
$highest_count = 0;
foreach($array AS $hex => $count)
{
    if ( $count > $highest_count )
    {
        $highest_hex = $hex;
        $highest_count = $count;
    }
}

echo "The most used color has hex code {$highest_hex} and was used {$highest_count} times.";

这是一种类似字典的(键值)方法。请注意,该数组的平均长度会小于您的数组,但最坏的情况将与您的数组长度相同(当所有像素都具有不同的颜色而没有重复时)。在这种情况下,在图像中找到的第一种颜色(左上角的第一个像素)将被认为是“最常用的”。

于 2013-09-21T23:44:15.603 回答