2012-10-16 34 views
5

Tôi có 10.000 hình ảnh tôi muốn sắp xếp theo màu để tạo thành bản in.Sắp xếp 10.000 hình ảnh theo màu

Tôi nhận được khá xa. Tôi đã trung bình màu sắc của họ vì vậy bây giờ tôi có hai thư mục: một với tất cả các hình ảnh gốc (original_images /), và một với jpegs bằng nhau có cùng màu trung bình (trung bình /).

Tiếp theo, tôi sử dụng PHP để sắp xếp các hình ảnh trung bình:

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

chỉnh sửa vấn đề là các phím $h dao động từ (rõ ràng) -0,1666666667 đến một nơi nào xung quanh 1. ruột của tôi nói rằng rất có thể là thực sự nhỏ mà có giá trị trùng lặp, nhưng trên thực tế có bật ra được hơn 6000 phím trùng lặp. Tôi đã cố gắng đúc giá trị $h cho một chuỗi bởi vì tôi nghĩ có lẽ các phím mảng được làm tròn?

Điều đó không hiệu quả. Đây là chức năng chuyển đổi rgb thành HSV. Tôi tìm thấy nó ở đâu đó mà không cần bất kỳ tài liệu ...

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; 
} 

Vì vậy, câu hỏi bây giờ là:

  1. Là rgb_to_hsv() - chức năng có đúng không?
  2. Làm cách nào để đảm bảo rằng các phím không bị ghi đè trong mảng, nhưng các giá trị được (chặt chẽ) được duy trì? Ví dụ; nếu hai hình ảnh có giá trị $ h là 0,01111111111, khi hình ảnh thứ hai được đẩy vào mảng, khóa của nó phải là 0,01111111112?

(chỉnh sửa cũ :) chỉnh sửa: Tôi đã thay đổi rename() để copy() vì vậy mà tôi không cần phải tải lên lại 10.000 hình ảnh mỗi lần nó đi sai ;-). Tôi cũng đã sử dụng ini_set("max_execution_time", 300); để tăng thời gian thực thi tối đa từ 60 lên 300, đã thêm imagedestroy($image) để giảm mức sử dụng bộ nhớ và cải thiện thành vòng lặp bằng cách thay đổi $i < count($images) thành $loop_limit = count($images).

chỉnh sửa 2: OK nên tôi đã tìm thấy sự cố. Giá trị $ h (Hue) cho các hình ảnh giống nhau ở mọi thời điểm hiện tại. Vì vậy, việc sử dụng sorted_images[$h] = $images[$i] sẽ ghi đè giá trị cho khóa đó trong mảng. Trong thực tế; có đến hơn 6000 giá trị trùng lặp ... Làm thế nào tôi sẽ đi và sửa chữa điều đó, mà không gây rối với giá trị $ h quá nhiều?

+2

Đừng quên 'imagedestroy ($ image);' sau các lần lặp của bạn. –

+1

'đếm ($ hình ảnh)' trong 'for' vòng lặp là một thực hành siêu tồi tệ nhất bao giờ hết! –

+0

ghi chú hợp lệ, cập nhật :). – Rein

Trả lời

1

Bạn đã thử bật thông báo lỗi chưa?

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

Đối với giá trị địa phương so với giá trị chính. 'cục bộ' có nghĩa là tập lệnh hiện đang chạy đang sử dụng hết thời gian chờ 300 giây. 'master' áp dụng cho tất cả các yêu cầu khác (trừ khi được sửa đổi rõ ràng)

Cron sẽ là một cách để đi, nhưng tôi không nghĩ việc này nên được thực thi nhiều lần trong mỗi X giây/phút/giờ? Bạn có thể chỉ cần sử dụng dòng lệnh để làm điều này.trông vào đây để biết thêm thông tin: http://www.php.net/manual/en/features.commandline.usage.php

Thấy như kịch bản làm việc đó rất có thể là một trong những vấn đề sau:

memory_limit không đủ cao. Nên cung cấp cho một lỗi PHP với các lỗi được kích hoạt. thời gian thực hiện không đủ cao. Nên cung cấp cho một lỗi PHP với các lỗi được kích hoạt.

sử dụng phương pháp init_set để tăng cả hai, nếu bạn 'chỉ' muốn tập lệnh chạy, hãy đặt thời gian chờ thành 0 giây và giới hạn bộ nhớ cao nhất có thể. Nếu bạn thực sự muốn biết nguyên nhân chính xác là gì, bạn có thể nghĩ đến việc tìm kiếm 'xdebug' để xem có rò rỉ bộ nhớ hay không, lệnh nào mất nhiều thời gian nhất để thực thi. Nhìn vào mã, tôi sẽ giả sử đó là lệnh sao chép mất một lúc để thực thi (sau đó 1ms, nhiều sau 10000 lần lặp lại)

Nếu sửa đổi các giá trị này không thể thực hiện được, hoặc bạn chỉ đơn giản là muốn đồ chơi xung quanh làm việc với các tập lệnh có thời gian thực thi với bộ nhớ dài, với các tài nguyên hạn chế, hãy thử viết lại tập lệnh để thực hiện đổi tên theo lô và đặt cron để thực thi tập lệnh mỗi X phút (chỉ cần xóa cron khi tất cả hình ảnh được thực hiện)

Chúc may mắn :)

+0

cảm ơn :-). Trong thực tế, tôi đang đóng trong vấn đề. Tôi đã sửa chữa kịch bản để có ít bộ nhớ hơn, mà luôn luôn là một điều tốt. Nhưng trên thực tế, tôi bắt đầu nghĩ rằng vấn đề nằm trong chính mảng đó. Vì một số lý do, ** ** nhiều khóa trong mảng bị ghi đè. Tôi sẽ cập nhật câu hỏi để phác thảo thêm điều này. – Rein

+1

phím màu, đặc biệt với 10000 hình ảnh có thể không đủ độc đáo. nó có thể không an toàn hơn để có các phím màu sắc thực sự chứa một mảng hình ảnh với tất cả các hình ảnh của màu sắc đó, thay vì chỉ một hình ảnh đơn (đơn giản: sắp xếp_images [$ h] [] = $ hình ảnh [$ i];) bạn sẽ cần phải thay đổi vòng lặp bản sao tho – Tjirp

1

Bạn có thể nhấn max_execution_time - Giới hạn thời gian tập lệnh được phép chạy. Hãy thử đặt giá trị cao hơn.

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

Bạn không nhận được thông báo lỗi?

+0

Không có thông báo lỗi! – Rein

+0

max_execution_time được đặt thành 60 master và 300 local. Tôi không chắc cái nào được sử dụng. – Rein

+1

@ReinoudSchuijers Bạn nên chạy các công việc như vậy trên cron. Đồng thời xem nhận xét của tôi về câu hỏi. Nó cũng sẽ tiêu tốn rất nhiều thời gian –