जावास्क्रिप्ट के माध्यम से छवि का औसत रंग प्राप्त करें


118

यह सुनिश्चित नहीं है कि यह संभव है, लेकिन एक ऐसी पटकथा लिखना है जो किसी छवि के लिए औसत hexया rgbमान लौटाए । मुझे पता है कि यह एएस में किया जा सकता है लेकिन इसे जावास्क्रिप्ट में करना है।


19
मेरा दोस्त बोअज़ इस रास्ते से पहले नीचे गया है (उम्मीद है कि वह झंकार करता है) लेकिन औसत आमतौर पर आपको उल्टी जैसा रंग देता है। आप वास्तव में क्या चाहते हैं "प्रमुख रंग"। वहाँ जाने के बारे में जाने के लिए कुछ तरीके हैं (ह्यू histogram w / गतिशील बकेटिंग आदि), लेकिन मुझे लगता है कि यह आपके इच्छित परिणाम के लिए संभवतः अधिक सटीक है।
पॉल आइरिश

जवाबों:


149

AFAIK, ऐसा करने का एकमात्र तरीका है <canvas/>...

DEMO V2 : http://jsfiddle.net/xLF38/818/

ध्यान दें, यह केवल उसी डोमेन और HTML5 कैनवास का समर्थन करने वाले ब्राउज़र में छवियों के साथ काम करेगा:

function getAverageRGB(imgEl) {

    var blockSize = 5, // only visit every 5 pixels
        defaultRGB = {r:0,g:0,b:0}, // for non-supporting envs
        canvas = document.createElement('canvas'),
        context = canvas.getContext && canvas.getContext('2d'),
        data, width, height,
        i = -4,
        length,
        rgb = {r:0,g:0,b:0},
        count = 0;

    if (!context) {
        return defaultRGB;
    }

    height = canvas.height = imgEl.naturalHeight || imgEl.offsetHeight || imgEl.height;
    width = canvas.width = imgEl.naturalWidth || imgEl.offsetWidth || imgEl.width;

    context.drawImage(imgEl, 0, 0);

    try {
        data = context.getImageData(0, 0, width, height);
    } catch(e) {
        /* security error, img on diff domain */
        return defaultRGB;
    }

    length = data.data.length;

    while ( (i += blockSize * 4) < length ) {
        ++count;
        rgb.r += data.data[i];
        rgb.g += data.data[i+1];
        rgb.b += data.data[i+2];
    }

    // ~~ used to floor values
    rgb.r = ~~(rgb.r/count);
    rgb.g = ~~(rgb.g/count);
    rgb.b = ~~(rgb.b/count);

    return rgb;

}

IE के लिए, एक्सनवास की जाँच करें ।


1
क्या एक अलग डोमेन पर पड़ी छवि के लिए रंग हिस्टोग्राम प्राप्त करने का कोई तरीका है?
डैन लोवेनहर्ज़

1
Dan: मुझे लगता है कि यदि आप किसी अन्य डोमेन से छवि पर छवि डेटा तक पहुंचने का प्रयास करते हैं, तो आप क्रॉस-मूल प्रतिबंध में चलते हैं। जो एक बमर है।

8
मुझे लगता है कि नीले और हरे रंग के मूल्य के लिए चिंताजनक स्थान है, आप लिखते हैं 'rgb('+rgb.r+','+rgb.b+','+rgb.g+')'और यह होना चाहिए 'rgb('+rgb.r+','+rgb.g+','+rgb.b+')'। यह अजीब है जब प्रमुख रंग नीला है, लेकिन परिणाम हरा है :)।
अरिओना रियान

7
क्रॉस-ऑरिजनल प्रतिबंधों के लिए एक महान समाधान मिला: विशेषता img.crossOrigin = '';स्थापित करने से पहले जोड़ें src। पर पाया: coderwall.com/p/pa-2uw
mhu

कोई ज़रूरत नहीं है, क्योंकि count === length / 4 / blockSize;)
22

84

मैंने हाल ही में एक प्रमुख रंग प्राप्त करने के लिए एक प्रोजेक्ट पोस्ट किया है:

रंग चोर

एक छवि से प्रमुख रंग या एक प्रतिनिधि रंग पैलेट को हथियाने के लिए एक स्क्रिप्ट। जावास्क्रिप्ट और कैनवास का उपयोग करता है।

प्रमुख रंग का उल्लेख और सुझाव देने वाले अन्य समाधान वास्तव में कभी भी उचित संदर्भ में प्रश्न का उत्तर नहीं देते हैं ("जावास्क्रिप्ट में")। उम्मीद है कि यह परियोजना उन लोगों की मदद करेगी जो सिर्फ ऐसा करना चाहते हैं।


55

"प्रमुख रंग" मुश्किल है। आप क्या करना चाहते हैं, प्रत्येक पिक्सेल और हर दूसरे पिक्सेल के बीच की दूरी को रंग अंतरिक्ष (यूक्लिडियन दूरी) में तुलना करें, और फिर उस पिक्सेल को ढूंढें जिसका रंग हर दूसरे रंग के सबसे करीब है। वह पिक्सेल प्रमुख रंग है। औसत रंग आमतौर पर कीचड़ होगा।

मेरी इच्छा है कि आपके पास यूक्लिडियन डिस्टेंस दिखाने के लिए मैं यहां मैथलएम हूं यह गूगल।

मैंने PHP / GD का उपयोग करके RGB रंग अंतरिक्ष में उपरोक्त निष्पादन पूरा किया है: https://gist.github.com/cf23f8bddb307ad4abd8

यह हालांकि बहुत कम्प्यूटेशनल रूप से महंगा है। यह बड़ी छवियों पर आपके सिस्टम को क्रैश कर देगा, और यदि आप क्लाइंट में इसे आज़माते हैं तो निश्चित रूप से आपके ब्राउज़र को क्रैश कर देगा। मैं अपने निष्पादन को फिर से करने पर काम कर रहा हूं: - प्रत्येक पिक्सेल पर पुनरावृत्ति में भविष्य के उपयोग के लिए एक लुकअप तालिका में स्टोर परिणाम। - स्थानीय प्रभुत्व के लिए बड़ी छवियों को 20px 20px के ग्रिड में विभाजित करना। - X1y1 और X1y3 के बीच की दूरी का पता लगाने के लिए X1y1 और X1y2 के बीच यूक्लिडियन दूरी का उपयोग करना।

यदि आप इस मोर्चे पर प्रगति करते हैं तो कृपया मुझे बताएं। मुझे यह देखकर खुशी होगी। मैं भी यही करूंगा।

कैनवस निश्चित रूप से क्लाइंट में ऐसा करने का सबसे अच्छा तरीका है। एसवीजी नहीं है, एसवीजी वेक्टर आधारित है। जब मैं निष्पादन को कम कर देता हूं, तो अगली चीज जो मैं करना चाहता हूं वह यह कैनवास में चल रही है (शायद प्रत्येक पिक्सेल की समग्र दूरी की गणना के लिए एक वेबवर्क के साथ)।

सोचने वाली एक और बात यह है कि आरजीबी ऐसा करने के लिए एक अच्छा रंग स्थान नहीं है, क्योंकि आरजीबी अंतरिक्ष में रंगों के बीच यूक्लिडियन दूरी दृश्य दूरी के बहुत करीब नहीं है। ऐसा करने के लिए एक बेहतर रंग स्थान एलयूवी हो सकता है, लेकिन मुझे इसके लिए एक अच्छा पुस्तकालय नहीं मिला है, या आरजीबी को एलयूवी में परिवर्तित करने के लिए कोई भी algorythims।

एक इंद्रधनुष में अपने रंगों को क्रमबद्ध करने के लिए एक पूरी तरह से अलग दृष्टिकोण होगा, और एक रंग के अलग-अलग रंगों के लिए सहिष्णुता के साथ हिस्टोग्राम का निर्माण करना होगा। मैंने यह कोशिश नहीं की है, क्योंकि एक इंद्रधनुष में रंगों को छांटना मुश्किल है, और इसलिए रंग हिस्टोग्राम हैं। मैं यह अगले कोशिश कर सकते हैं। फिर से, मुझे बताएं कि क्या आप यहां कोई प्रगति करते हैं।


6
यह उन उत्तरों में से एक है जिसके लिए मैं चाहता हूं कि मैं केवल +1 :-) से अधिक कर सकता हूं
डेविड जॉनस्टोन

3
उत्कृष्ट जवाब भले ही एक स्पष्ट समाधान प्रदान नहीं किया गया था। यह मुझे मेरा अगला कदम तय करने में मदद करेगा ...
14

यह एक महान जवाब है। मैंने एलयूवी में नहीं, बल्कि एल बी * रंग अंतरिक्ष में यूक्लिडियन दूरी की गणना करने के लिए कुछ नोड मॉड्यूल लिखे । देखें github.com/zeke/color-namer और github.com/zeke/euclidean-distance
Zeke

1
@user: मैं बस सोच रहा था: एक, कहना नहीं होगा, 1% नमूना बड़े चित्रों पर गणना की गति बढ़ाने के लिए पर्याप्त है?
१२

ज्यामितीय माध्यिका की तरह लगता है। शायद यह मदद कर सकता है? stackoverflow.com/questions/12934213/... और आप देख रहे हैं बिंदु यदि जरूरी : मूल सेट में अस्तित्व en.m.wikipedia.org/wiki/Medoid#Algorithms_to_compute_medoids
लॉरेंस Weru

16

पहला: यह एचटीएमएल 5 कैनवस या एसवीजी के बिना किया जा सकता है।
वास्तव में, किसी को सिर्फ करने में कामयाब रहे जावास्क्रिप्ट का उपयोग क्लाइंट साइड PNG फ़ाइलें उत्पन्न , बिना कैनवास या एसवीजी, का उपयोग कर डेटा URI योजना

दूसरा: आपको वास्तव में कैनवस, एसवीजी या उपरोक्त सभी में से किसी की आवश्यकता नहीं हो सकती है।
यदि आपको केवल क्लाइंट पक्ष पर छवियों को संसाधित करने की आवश्यकता है , तो उन्हें संशोधित किए बिना , यह सब आवश्यक नहीं है।

आप पृष्ठ पर img टैग से स्रोत का पता प्राप्त कर सकते हैं, इसके लिए एक्सएचआर अनुरोध कर सकते हैं - यह संभवतः ब्राउज़र कैश से आएगा - और इसे जावास्क्रिप्ट से बाइट स्ट्रीम के रूप में संसाधित करेगा।
आपको छवि प्रारूप की अच्छी समझ की आवश्यकता होगी। (उपरोक्त जनरेटर आंशिक रूप से libpng स्रोतों पर आधारित है और एक अच्छा प्रारंभिक बिंदु प्रदान कर सकता है।)


बाईटस्ट्रीम समाधान के लिए +1। यह एक अच्छा है अगर ग्राहक विकल्प पर इसे बनाने का एकमात्र विकल्प है।
लोरेटोपारसी

11

मैं HTML कैनवास टैग के माध्यम से कहूंगा।

आप यहां ओपेरा देव द्वारा एक छोटे कोड के बारे में बात कर @Georg द्वारा एक पोस्ट पा सकते हैं :

// Get the CanvasPixelArray from the given coordinates and dimensions.
var imgd = context.getImageData(x, y, width, height);
var pix = imgd.data;

// Loop over each pixel and invert the color.
for (var i = 0, n = pix.length; i < n; i += 4) {
    pix[i  ] = 255 - pix[i  ]; // red
    pix[i+1] = 255 - pix[i+1]; // green
    pix[i+2] = 255 - pix[i+2]; // blue
    // i+3 is alpha (the fourth element)
}

// Draw the ImageData at the given (x,y) coordinates.
context.putImageData(imgd, x, y);

यह प्रत्येक पिक्सेल के R, G और B मान का उपयोग करके छवि को उल्टा करता है। आप आसानी से RGB मानों को संग्रहीत कर सकते हैं, फिर लाल, हरे और नीले सरणियों को गोल कर सकते हैं, और अंत में उन्हें वापस HEX कोड में परिवर्तित कर सकते हैं।


किसी भी मौका कैनवास समाधान के लिए एक IE विकल्प है?
bgitory

@ Ben4Himv: IE9 प्लेटफ़ॉर्म पूर्वावलोकन;; लेकिन गंभीरता से, मुझे डर नहीं है।
एंडी ई


4

जावास्क्रिप्ट में एक छवि के अलग-अलग पिक्सेल रंग डेटा तक पहुंच नहीं है। कम से कम, शायद नहीं html5 तक ... जिस बिंदु पर यह इस कारण से खड़ा होता है कि आप एक कैनवास पर एक छवि बनाने में सक्षम होंगे, और फिर कैनवास का निरीक्षण करेंगे (हो सकता है, मैंने इसे खुद कभी नहीं किया हो)।


2

ऑल-इन-वन सॉल्यूशन

मैं व्यक्तिगत रूप से नाम के इस संशोधित संस्करण के साथ कलर चोर को संयोजित करूंगा कि छवियों के लिए प्रमुख रंग परिणामों का अधिक से अधिक पर्याप्त सरणी प्राप्त करने के लिए रंग।

उदाहरण:

निम्नलिखित छवि पर विचार करें:

यहां छवि विवरण दर्ज करें

प्रमुख रंग से संबंधित छवि डेटा निकालने के लिए आप निम्न कोड का उपयोग कर सकते हैं:

let color_thief = new ColorThief();
let sample_image = new Image();

sample_image.onload = () => {
  let result = ntc.name('#' + color_thief.getColor(sample_image).map(x => {
    const hex = x.toString(16);
    return hex.length === 1 ? '0' + hex : hex;
    
  }).join(''));
  
  console.log(result[0]); // #f0c420     : Dominant HEX/RGB value of closest match
  console.log(result[1]); // Moon Yellow : Dominant specific color name of closest match
  console.log(result[2]); // #ffff00     : Dominant HEX/RGB value of shade of closest match
  console.log(result[3]); // Yellow      : Dominant color name of shade of closest match
  console.log(result[4]); // false       : True if exact color match
};

sample_image.crossOrigin = 'anonymous';
sample_image.src = document.getElementById('sample-image').src;

1

यह "कलर क्वांटाइज़ेशन " के बारे में है जिसमें MMCQ (संशोधित मेडियन कट क्वांटिज़ेशन) या OQ (ऑक्ट्री क्वांटिज़ेशन) जैसे कई दृष्टिकोण हैं । विभिन्न दृष्टिकोण रंगों के समूहों को प्राप्त करने के लिए के -मीन्स का उपयोग करते हैं।

मैंने यहां सभी को एक साथ रखा है, क्योंकि मुझे एक समाधान मिल रहा है tvOSजहां एक्सएचटीएमएल का सबसेट है, जिसमें कोई <canvas/>तत्व नहीं है:

XMLHttpRequest के साथ RGB छवि के लिए प्रमुख रंग उत्पन्न करें


1

datauriसमर्थन के साथ छवि का औसत रंग प्राप्त करने के लिए कम सटीक लेकिन सबसे तेज़ तरीका :

function get_average_rgb(img) {
    var context = document.createElement('canvas').getContext('2d');
    if (typeof img == 'string') {
        var src = img;
        img = new Image;
        img.setAttribute('crossOrigin', ''); 
        img.src = src;
    }
    context.imageSmoothingEnabled = true;
    context.drawImage(img, 0, 0, 1, 1);
    return context.getImageData(1, 1, 1, 1).data.slice(0,3);
}

1

जैसा कि अन्य जवाबों में कहा गया है, अक्सर आप वास्तव में प्रमुख रंग के विपरीत औसत रंग चाहते हैं जो भूरा हो जाता है। मैंने एक पटकथा लिखी जो सबसे आम रंग है और इसे इस गेस पर पोस्ट किया है


-2

एक ऑनलाइन टूल pickimagecolor.com है जो आपको छवि का औसत या प्रमुख रंग खोजने में मदद करता है। आपको बस अपने कंप्यूटर से एक छवि अपलोड करनी है और फिर छवि पर क्लिक करना है। यह एचईएक्स, आरजीबी और एचएसवी में औसत रंग देता है। यह उस रंग से मेल खाते रंग रंगों को भी चुनता है। मैंने कई बार इसका इस्तेमाल किया है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.