PHP

2009-10-27 9 views
12

में रंगों के बीच "दूरी" मैं एक ऐसे फ़ंक्शन की तलाश में हूं जो दो रंगों के बीच दूरी या किसी चीज़ के बीच दूरी का सटीक रूप से प्रतिनिधित्व कर सके।PHP

उदाहरण के लिए मैं हेक्स मूल्यों या आरजीबी सरणियों की एक सरणी है के लिए देख रहा हूँ और मैं किसी दिए गए रंग

उदाहरण के लिए सरणी में सबसे अधिक समान रंग लगाना चाहते हैं। मैं एक समारोह को एक आरजीबी मान पास करता हूं और सरणी में 'निकटतम' रंग वापस आ जाता है

+0

इसी प्रकार का प्रश्न: http://stackoverflow.com/questions/1313/followup-finding-an-accurate-distance-between-colors – Kai

उत्तर

19

प्रत्येक रंग को हेक्स कोड में टुपल के रूप में दर्शाया जाता है। करीबी मैचों को निर्धारित करने के लिए आपको प्रत्येक आरजीबी घटक को अलग से घटाना होगा।

उदाहरण:

Color 1: #112233 
Color 2: #122334 
Color 3: #000000 

Difference between color1 and color2: R=1, G=1 B=1 = 0x3 
Difference between color3 and color1: R=11, G=22, B=33 = 0x66 

So color 1 and color 2 are closer than 
1 and 3. 

संपादित

तो तुम सबसे करीब नामित रंग करना चाहते हैं? प्रत्येक रंग के हेक्स मानों के साथ एक सरणी बनाएं, इसे पुन: सक्रिय करें और नाम वापस करें। कुछ इस तरह;

function getColor($rgb) 
{ 
    // these are not the actual rgb values 
    $colors = array(BLUE =>0xFFEEBB, RED => 0x103ABD, GREEN => 0x123456); 

    $largestDiff = 0; 
    $closestColor = ""; 
    foreach ($colors as $name => $rgbColor) 
    { 
     if (colorDiff($rgbColor,$rgb) > $largestDiff) 
     { 
      $largestDiff = colorDiff($rgbColor,$rgb); 
      $closestColor = $name; 
     } 

    } 
    return $closestColor; 

} 

function colorDiff($rgb1,$rgb2) 
{ 
    // do the math on each tuple 
    // could use bitwise operates more efficiently but just do strings for now. 
    $red1 = hexdec(substr($rgb1,0,2)); 
    $green1 = hexdec(substr($rgb1,2,2)); 
    $blue1 = hexdec(substr($rgb1,4,2)); 

    $red2 = hexdec(substr($rgb2,0,2)); 
    $green2 = hexdec(substr($rgb2,2,2)); 
    $blue2 = hexdec(substr($rgb2,4,2)); 

    return abs($red1 - $red2) + abs($green1 - $green2) + abs($blue1 - $blue2) ; 

} 
+0

मुझे समझ में आता है कि मुझे आरजीबी मूल्य प्राप्त करने की आवश्यकता है, लेकिन मैं एक फ़ंक्शन की तलाश में हूं किसी दिए गए रंग के लिए सरणी में "सबसे समान" रंग वापस कर सकता है। एक साधारण उदाहरण: [नीला, लाल, DARKRED, ग्रीन] समारोह रंग lightblue, ऊपर सरणी से, ईद उम्मीद समारोह "ब्लू" लौटने के लिए चीयर्स फिलिप – Phil

+0

आप अगर दिया गया था, तो हेक्स वैल्यू पर मुकदमा नहीं कर रहे हैं, बस एक बड़े स्विच स्टेटमेंट के साथ एक फ़ंक्शन बनाएं जो रंग का नाम लेता है और जो आपको लगता है वह सबसे नज़दीकी रंग का नाम देता है। –

+3

colofDiff फ़ंक्शन अच्छा है, लेकिन बदले में एक बग ठीक करना है, "वापसी पेट ($ red1 - $ red2) + abs ($ green1 - $ green2) + abs ($ blue1 - $ blue2);" – Cesar

4

तीन आयामों के बीच सारांशित दूरी की गणना करना एक बहुत ही सरल तरीका है। उदाहरण के लिए simple_distance ("12,10,255", "10,10,250") = 7

एक और परिष्कृत दृष्टिकोण प्रत्येक घटकों के लिए दूरी के वर्ग को लेना होगा और उनको जोड़ना होगा - इस तरह से घटक बहुत दूर होंगे "दंडित" अधिक: square_distance ("12,10,255", "10,10,250") = 2 * 2 + 0 * 0 + 5 * 5 = 2 9।

बेशक आपको रंगों की सूची में पुन: प्रयास करना होगा और निकटतम को ढूंढना होगा।

1

आप अपने आरजीबी मूल्य को एचएसएल या एचएसवी में परिवर्तित कर सकते हैं। तो रंगों की तुलना करना आसान होता है: क्रमशः रंगों को ऑर्डर करके, फिर संतृप्ति द्वारा, फिर चमक से। परिणामी क्रम में, एक-दूसरे के बगल में 2 रंग अवधारणात्मक रूप से बहुत करीब के रूप में दिखाई देंगे।

सावधान रहें कि ह्यू लपेटें: 0 से 255 तक के रंग के लिए, 0 का एक रंग और 255 का रंग बहुत करीब है।

सूत्र है जो आप एचएसएल

लिए आरजीबी रूपांतरित कर सकेगा लिए एचएसएल http://en.wikipedia.org/wiki/HSL_and_HSV पर विकिपीडिया लेख देखें (ध्यान दें कि अन्य रंग रिक्त स्थान, लैब की तरह, बेहतर परिणाम दे सकता है, लेकिन रूपांतरण अधिक जटिल है)

के गणितीय इस को परिभाषित करते हैं:

distance(A(h,s,l), B(h,s,l)) = (A(h)-B(h)) * F^2 + (A(s)-B(s)) * F + (A(l)-B(l)) 

जहां एफ एक पहलू को ध्यान से चुना है (256 की तरह कुछ ...)

उपरोक्त फॉर्मूला में ह्यू रैपरराउंड नहीं है ...

+0

यह कोई मतलब नहीं है। यदि रंग ए और बी में ल्यूमिनेंस और एक ही रंग में थोड़ा अंतर था, और रंग ए और सी के समान चमक था और रंग में एक बड़ा अंतर था (कहें कि लाल है और दूसरा हरा है ...), ए और ए के बीच की दूरी बी ए और सी के बीच की दूरी से अधिक होगा ... –

+0

ऐसा लगता है कि आप ऑर्डर करने के आदेश को गलत समझाते हैं: आप पहले ह्यू द्वारा ऑर्डर करते हैं, फिर आप संतृप्ति के बराबर रंग के साथ रंग ऑर्डर करते हैं, अंततः आप समान रंग और संतृप्ति के साथ रंगों को ऑर्डर करते हैं। इस आदेश को देखते हुए, रंग ए और बी में एक ही रंग है और दूरी (ए, बी) (ए, सी) से छोटी है। –

+0

मैंने एक छोटा गणितीय सूत्र शामिल करने के लिए अपना उत्तर संपादित किया, जो मुझे आशा है कि ऑर्डरिंग को बेहतर ढंग से समझने में मदद मिलेगी ... –

12

Here is a paper on the subject जो एक अच्छा जवाब देना चाहिए।

मैं सोच रहा था कि एचएसएल/एचएसवी में कनवर्ट करना सबसे अच्छा विचार होगा, लेकिन फिर मुझे एहसास हुआ कि एस & एल/वी के चरम मूल्यों पर, एच कोई फर्क नहीं पड़ता, और बीच में, यह सबसे महत्वपूर्ण है ।

मुझे लगता है कि यदि आप एक साधारण समाधान चाहते हैं, तो आरजीबी स्पेस में रहना बुद्धिमान होगा। मैं कार्टेशियन दूरी का उपयोग करूंगा। आप कई i के लिए Ri Gi Bi के खिलाफ रंग R G B पर विचार कर रहे हैं, तो आप i कि कम से कम

(R - Ri)^2 + (G - Gi)^2 + (B - Bi)^2 
8

सबसे पहले आप वें उचित रंग स्थान आप रंग की तुलना (आरजीबी, एचएसवी, एचएसएल में होते हैं करना चाहते हैं चुनने के लिए चाहते हैं, सीएमवाईके, आदि)।

मान लिया जाये कि आप को पता है कितने करीब 3-dimenionsal आरजीबी अंतरिक्ष में दो अंक एक दूसरे के लिए कर रहे हैं चाहते हैं, आप उन दोनों के बीच पाइथागोरस दूरी की गणना कर सकते हैं, यानी,

d2 = (r1 - r2)**2 + (g1 - g2)**2 + (b1 - b2)**2; 

यह वास्तव में आप के वर्ग देता है दुरी। (यदि आप केवल वर्ग मानों की तुलना कर रहे हैं तो वर्ग रूट लेना आवश्यक नहीं है।)

यह मानता है कि आप आर, जी और बी मानों को समान रूप से देखना चाहते हैं। यदि आप इसके बजाय इस तरह होता है क्या जब आप ग्रेस्केल में आरजीबी परिवर्तित रूप में अलग-अलग रंग के घटकों, वजन चाहते हैं तो आप दूरी के प्रत्येक शब्द, यानी करने के लिए एक गुणांक को जोड़ने के लिए,

d2 = 30*(r1-r2)**2 + 59*(g1-g2)**2 + 11*(b1-b2)**2; 

इस से लोकप्रिय रूपांतरण मान लिया गया है आरजीबी 30% लाल + 59% हरा + 11% नीला ग्रेस्केल करने के लिए।

अद्यतन

पिछले समीकरण शायद होना चाहिए कि

d2 = (30*(r1-r2))**2 + (59*(g1-g2))**2 + (11*(b1-b2))**2; 
संबंधित मुद्दे