2012-10-16 76 views
5

我有10,000張圖像我想按顏色進行排序以便打印。按顏色對10,000個圖像進行排序

我越來越遠了。我平均他們的顏色,所以現在我有兩個目錄:一個與所有的原始圖像(original_images /),一個與他們的平均顏色(平均值/)同名的jpegs。

接下來,我用PHP的平均圖像進行排序:該鍵$h範圍(顯然)-0.1666666667圍繞地方1.我的直覺說,機會是

// $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); 

編輯問題真的很小,有重複的值,但實際上有超過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; 
} 

所以,現在的問題是:

  1. 是在rgb_to_hsv() - 函數是否正確?
  2. 如何確保密鑰未在數組中覆蓋,但值(緊密)保持不變?例如;如果兩個圖像的$ h值爲0.01111111111,那麼當第二個圖像被推入陣列時,它的關鍵應該是0.01111111112?

(老編輯:) 編輯:我已經改變了rename()copy(),讓我不必在每次出了問題;-)時間來重新上傳10,000張。我還使用ini_set("max_execution_time", 300);將最大執行時間從60增加到300,並添加imagedestroy($image)以減少內存使用量,並通過將$i < count($images)更改爲$loop_limit = count($images)將其改進爲for-loop。

編輯2:好吧,所以我發現了一個問題。圖像的$ h(Hue)值每隔一段時間都是相同的。因此使用sorted_images[$h] = $images[$i]將覆蓋該數組中該鍵的值。事實上;結果是有超過6000個重複值...我怎麼去解決這個問題,而不會過多地弄亂$ h值?

+2

不要忘記''imagedestroy($ image);'在你的迭代之後。 –

+1

'count($ images)'在'for'循環中是有史以來超級最差的練習! –

+0

正式注意,更新:)。 – Rein

回答

1

您是否嘗試過啓用錯誤消息?

error_reporting(E_ALL); 
ini_set('display_errors', 1); 

至於本地值和主值。 '本地'意味着當前正在運行的腳本正在使用300秒的超時時間。 '主'適用於所有其他請求(除非明確修改)

Cron將是一種方式,但我認爲這不應該每X秒/分鐘/小時執行多次?你可以簡單地使用命令行來做到這一點。看看這裏的更多信息:http://www.php.net/manual/en/features.commandline.usage.php

看到作爲腳本作品是最有可能的下列問題之一:

memory_limit的不夠高。應該給錯誤啓用PHP錯誤。 執行時間不夠高。應該給錯誤啓用PHP錯誤。

使用init_set方法來提高這兩種,如果你「只是」希望腳本運行,設置超時時間爲0秒,內存限制高,你可以走了。如果你想真正瞭解究竟是什麼原因,你可以考慮查找'xdebug'來查看是否有任何內存泄漏或哪些命令需要最長時間執行。看代碼,我會假設它是需要一段時間才能執行的複製命令(超過1ms,這在10000次迭代後是很多的)

如果修改這些值無法完成,或者您只是想玩具使用高內存,資源有限的長執行時間腳本,嘗試重寫腳本以批量執行重命名,並設置一個cron,以便每X分鐘執行一次腳本(只需在完成所有映像時刪除cron)

祝你好運:)

+0

謝謝:-)。事實上,我正在關注這個問題。我確實修復了腳本,減少了內存密集度,這總是一件好事。但事實上,我開始認爲問題在於陣列本身。出於某種原因,數組中的密鑰**會被覆蓋。我會更新這個問題來進一步概述這一點。 – Rein

+1

色調鍵,特別是10000個圖像可能不夠獨特。如果色調鍵實際上包含具有該色調的所有圖像的圖像數組,則可能更安全,而不是僅包含單個圖像(simple:sorted_images [$ h] [] = $ images [$ i];)需要更改複製循環壽 – Tjirp

1

您可能會遇到max_execution_time - 允許腳本運行的時間限制。嘗試設置更高的值。

http://php.net/manual/de/function.set-time-limit.php

不要你收到任何錯誤訊息?

+0

沒有錯誤信息! – Rein

+0

max_execution_time設置爲60個主設備和300個本地設備。我不確定使用哪一個。 – Rein

+1

@ReinoudSchuijers你應該在cron上運行這樣的工作。另請參閱我對問題的評論。它也將消耗大量時間 –