色で並べ替えて印刷したい画像が 10,000 枚あります。
私はかなり遠くまで来ています。色を平均化したので、2 つのディレクトリができました。1 つはすべての元の画像 (original_images/) で、もう 1 つは平均色の同じ名前の jpeg (averages/) です。
次に、PHP を使用して平均画像を並べ替えます。
// $images is an array with all the filenames.
$sorted_images = array();
$loop_limit = count($images);
for($i = 0; $i < $loop_limit; $i++) {
$image = imagecreatefromjpeg("averages/" . $images[$i]);
$rgb = imagecolorat($image, 50, 50);
imagedestroy($image);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
$hsv = rgb_to_hsv($r, $g, $b); // function to convert rgb to Hue/Sat/Value
$h = (string) $hsv['H'];
if(isset($sorted_h[$h])) {
$duplicates++;
echo("oh no! " . $h . " is a dupe! found " . $duplicates . " duplicates so far.<br>");
}
$sorted_h[$h] = $images[$i];
}
// sort the array by key:
ksort($sorted_images, SORT_NUMERIC);
問題を編集すると、キーの$h
範囲は (どうやら) -0.1666666667 から 1 付近までです。値が重複する可能性は非常に小さいと直感的に言えますが、実際には 6000 を超える重複キーがあることが判明しました。$h
配列キーが丸められているのではないかと思ったので、値を文字列にキャストしてみましたか?
しかし、それはうまくいきませんでした。RGBをHSVに変換する関数です。どこかでドキュメントなしで見つけました...
function RGB_TO_HSV ($R, $G, $B) {
$HSV = array();
$var_R = ($R / 255);
$var_G = ($G / 255);
$var_B = ($B / 255);
$var_Min = min($var_R, $var_G, $var_B);
$var_Max = max($var_R, $var_G, $var_B);
$del_Max = $var_Max - $var_Min;
$V = $var_Max;
if ($del_Max == 0)
{
$H = 0;
$S = 0;
}
else
{
$S = $del_Max / $var_Max;
$del_R = ( ( ( $max - $var_R ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;
$del_G = ( ( ( $max - $var_G ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;
$del_B = ( ( ( $max - $var_B ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;
if ($var_R == $var_Max) $H = $del_B - $del_G;
else if ($var_G == $var_Max) $H = ( 1 / 3 ) + $del_R - $del_B;
else if ($var_B == $var_Max) $H = ( 2 / 3 ) + $del_G - $del_R;
if (H<0) $H++;
if (H>1) $H--;
}
$HSV['H'] = $H;
$HSV['S'] = $S;
$HSV['V'] = $V;
return $HSV;
}
したがって、現在の質問は次のとおりです。
- rgb_to_hsv() 関数は正しいですか?
- キーが配列で上書きされないようにするにはどうすればよいですか? 例えば; 2 つの画像の $h-value が 0.01111111111 の場合、2 番目の画像が配列にプッシュされると、そのキーは 0.01111111112 になりますか?
(古い編集:)
編集:問題が発生するたびに 10,000 枚の画像を再アップロードする必要がないように変更rename()
しました ;-)。copy()
またini_set("max_execution_time", 300);
、最大実行時間を 60 から 300 に増やしimagedestroy($image)
、メモリ使用量を減らすために追加し、に変更$i < count($images)
して for ループに改善しました$loop_limit = count($images)
。
編集 2:問題が見つかりました。画像の $h (色相) 値は時々同じです。したがって、使用sorted_images[$h] = $images[$i]
すると、配列内のそのキーの値が上書きされます。実際には; 6000 を超える重複値があることが判明しました... $h 値をあまりいじらずに、どうすればそれを修正できますか?