我有10,000张图像,我想按颜色排序以进行打印。
我已经走得很远了。我已经平均了他们的颜色,所以现在我有两个目录:一个包含所有原始图像(original_images /),另一个包含平均颜色的平均颜色(平均值/)。
接下来,我使用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;
}
现在的问题是:
(旧编辑:)
修改:我已将rename()
更改为copy()
,这样每次出错时我都无需重新上传10,000张图片;-)。我还使用ini_set("max_execution_time", 300);
将最高执行时间从60增加到300,添加imagedestroy($image)
以减少内存使用量,并通过将$i < count($images)
更改为$loop_limit = count($images)
来改进for for循环
编辑2:好的,所以我发现了一个问题。图像的$ h(Hue)值时不时相同。因此,使用sorted_images[$h] = $images[$i]
会覆盖数组中该键的值。事实上;结果是超过6000个重复的值...我怎样才能解决这个问题,而不会过多地贬低$ h值?
答案 0 :(得分:1)
您可能会遇到max_execution_time - 允许脚本运行的时间限制。尝试设置更高的值。
http://php.net/manual/de/function.set-time-limit.php
您是否收到任何错误消息?
答案 1 :(得分:1)
您是否尝试过启用错误消息?
error_reporting(E_ALL);
ini_set('display_errors', 1);
至于本地vs主值。 'local'表示当前运行的脚本使用300秒的超时。 'master'适用于所有其他请求(除非明确修改)
Cron是一种可行的方式,但我不认为这应该每X秒/分钟/小时执行多次?您可以自己使用命令行来执行此操作。在此处查看更多信息:http://www.php.net/manual/en/features.commandline.usage.php
看到脚本有效,它很可能是以下问题之一:
memory_limit不够高。应该在启用错误的情况下给出PHP错误。 执行时间不够高。应该在启用错误的情况下给出PHP错误。
使用init_set方法增加两者,如果你只是想让脚本运行,将timeout设置为0秒,内存限制尽可能高。如果你想真正了解究竟是什么原因,你可能会考虑查找'xdebug'以查看是否存在任何内存泄漏或哪些命令执行时间最长。看一下代码,我假设复制命令需要一段时间才能执行(超过1ms,10000次迭代后很多)
如果无法修改这些值,或者您只是想使用资源有限的高内存,长执行时脚本,请尝试重写脚本以批量执行重命名并将cron设置为每隔X分钟执行一次脚本(只需在完成所有图像后删除cron)
祝你好运:)