জাভাস্ক্রিপ্টের মাধ্যমে চিত্রের গড় রঙ পান


118

নিশ্চিত যে এটি সম্ভব, তবে কোনও স্ক্রিপ্ট লিখতে চাইছেন যা কোনও চিত্রের গড় hexবা rgbমান ফেরত দেয় । আমি জানি এটি এএস এ করা যেতে পারে তবে জাভাস্ক্রিপ্টে এটি করার চেষ্টা করছেন।


19
আমার বন্ধু বোয়াজ এর আগে এই পথে নেমেছিল (আশা করি সে চিমসে) তবে গড় সাধারণত আপনাকে বমির মতো রঙ দেয়। আপনি যা চান তা হ'ল "প্রভাবশালী রঙ"। এটি পাওয়ার জন্য কয়েকটি উপায় রয়েছে (হিস্টোগ্রাম ডাব্লু / ডায়নামিক বালতি ইত্যাদি) তবে আমি মনে করি এটি সম্ভবত আপনার উদ্দেশ্যযুক্ত ফলাফলের জন্য আরও সুনির্দিষ্ট।
পল আইরিশ

উত্তর:


149

আফাইক, এটি করার একমাত্র উপায় হ'ল <canvas/>...

ডেমো ভি 2 : http://jsfiddle.net/xLF38/818/

দ্রষ্টব্য, এটি কেবল একই ডোমেনের চিত্র এবং ব্রাউজারগুলিতে কাজ করবে যা এইচটিএমএল 5 ক্যানভাস সমর্থন করে:

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;

}

আই-এর জন্য এক্সানভান্স পরীক্ষা করে দেখুন


1
কোনও আলাদা ডোমেনে থাকা কোনও চিত্রের জন্য রঙিন হিস্টোগ্রাম পাওয়ার কোনও উপায় আছে কি?
ড্যান লোয়েনেহার্জ

1
ড্যান: আমি মনে করি আপনি অন্য ডোমেন থেকে কোনও চিত্রের চিত্রের ডেটা অ্যাক্সেস করার চেষ্টা করলে আপনি ক্রস-অরিজিন সীমাবদ্ধতায় চলে যান। যা একটি বোমা।

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;)
yckart

84

অনুভূত যে আমি একটি প্রকল্প পোস্ট করেছি যা আমি সম্প্রতি প্রভাবশালী রঙ পেতে পেরেছি:

রঙ চোর

প্রভাবশালী রঙ বা চিত্র থেকে একটি প্রতিনিধি রঙ প্যালেট দখল করার জন্য একটি স্ক্রিপ্ট। জাভাস্ক্রিপ্ট এবং ক্যানভাস ব্যবহার করে।

প্রভাবশালী রঙের উল্লেখ এবং প্রস্তাবিত অন্যান্য সমাধানগুলি সঠিক প্রসঙ্গে ("জাভাস্ক্রিপ্টে") সত্যই উত্তর দেয় না। আশা করি এই প্রকল্পটি যারা তাদের কেবল এটি করতে চায় তাদের সহায়তা করবে।


55

"আধিপত্যবাদী রঙ" কৃপণ। আপনি যা করতে চান তা হল প্রতিটি পিক্সেল এবং রঙের স্থানের প্রতিটি পিক্সেলের মধ্যে দূরত্বের তুলনা (ইউক্লিডিয়ান দূরত্ব) এবং তারপরে পিক্সেলটি খুঁজে নিন যার রঙটি প্রতিটি অন্যান্য বর্ণের সবচেয়ে কাছের। সেই পিক্সেলটি হ'ল প্রভাবশালী রঙ। গড় রঙ সাধারণত কাদা হবে।

আমি আপনাকে ইউক্যালিডিয়ান দূরত্ব দেখানোর জন্য এখানে ম্যাথএমএল করার ইচ্ছা করি। গুগলে খোজুন.

আমি এখানে পিএইচপি / জিডি ব্যবহার করে আরজিবি রঙের স্পেসে উপরের সম্পাদন সম্পাদন করেছি: https://gist.github.com/cf23f8bddb307ad4abd8

এটি তবে খুব গণ্য ব্যয়বহুল। এটি আপনার সিস্টেমে বড় চিত্রগুলিতে ক্রাশ হবে এবং আপনি যদি ক্লায়েন্টে চেষ্টা করেন তবে আপনার ব্রাউজারটি অবশ্যই ক্রাশ হবে। আমি আমার এক্সিকিউশনটিকে রিফ্যাক্টর করার কাজ করছি: - প্রতিটি পিক্সেলের উপরে পুনরাবৃত্তিতে ভবিষ্যতের ব্যবহারের জন্য অনুসন্ধান সারণিতে ফলাফল সঞ্চয় করে store - স্থানীয় আধিপত্যের জন্য বৃহত চিত্রগুলিকে 20px 20px এর গ্রিডে বিভক্ত করতে। - x1y1 এবং x1y3 এর মধ্যে দূরত্ব নির্ধারণ করতে x1y1 এবং x1y2 এর মধ্যে ইউক্লিডিয়ান দূরত্ব ব্যবহার করতে।

আপনি যদি এই ফ্রন্টে অগ্রগতি করেন তবে দয়া করে আমাকে জানান। আমি এটি দেখতে খুশি হবে। আমি একই কাজ করবো.

ক্যানভাস অবশ্যই ক্লায়েন্টে এটি করার সর্বোত্তম উপায়। এসভিজি নয়, এসভিজি ভেক্টর ভিত্তিক। আমি মৃত্যুদন্ড কার্যকর করার পরে, পরবর্তী কাজটি করতে চাই তা হল ক্যানভাসে এই চলমানটি (সম্ভবত প্রতিটি পিক্সেলের সামগ্রিক দূরত্ব গণনার জন্য ওয়েবকারীর সাথে)।

আর একটি বিষয় যা ভাবতে হবে তা হ'ল আরজিবি এটি করার জন্য ভাল রঙের স্থান নয় কারণ আরজিবি স্পেসে বর্ণের মধ্যে ইউক্লিডিয়ান দূরত্ব ভিজ্যুয়াল দূরত্বের খুব কাছাকাছি নয়। এটি করার জন্য আরও ভাল রঙের জায়গাটি সম্ভবত এলইউভি হতে পারে তবে আরজিবিকে এলইউভিতে রূপান্তর করার জন্য আমি এর জন্য ভাল লাইব্রেরি বা কোনও অ্যালগরিথিম খুঁজে পাইনি।

একটি সম্পূর্ণ ভিন্ন পদ্ধতি হ'ল আপনার রংকে একটি রংধনুতে বাছাই করা, এবং রঙের বিভিন্ন শেডের জন্য অ্যাকাউন্টে সহনশীলতার সাথে একটি হিস্টোগ্রাম তৈরি করা। আমি এটি চেষ্টা করি নি, কারণ একটি রংধনুতে রঙ বাছাই করা শক্ত এবং একই সাথে রঙের হিস্টোগ্রামগুলি। আমি এটি পরবর্তী চেষ্টা করতে পারেন। আবার, আপনি যদি এখানে কোনও অগ্রগতি করেন তবে আমাকে জানান।


6
এটি সেই উত্তরগুলির মধ্যে একটি যা আমি আশা করি যে আমি কেবল +1 :-) এর চেয়ে বেশি কিছু করতে পারব
ডেভিড জনস্টোন

3
যদিও একটি পরিষ্কার সমাধান সরবরাহ করা হয়নি সত্ত্বেও দুর্দান্ত উত্তর। এটি আমার পরবর্তী পদক্ষেপটি আমাকে সিদ্ধান্ত নিতে সহায়তা করবে ...
বিগ্রেটার

এটি একটি দুর্দান্ত উত্তর। ইউক্যালিডিয়ান দূরত্ব গণনা করতে আমি কয়েকটি নোড মডিউল লিখেছি এলইউভিতে নয়, এল বি * রঙের জায়গাতে। দেখুন github.com/zeke/color-namer এবং github.com/zeke/euclidean-distance
Zeke

1
@ ব্যবহারকারীর: আমি কেবল ভাবছিলাম: একটি, বলার অপেক্ষা রাখে না যে গণনার গতি বাড়ানোর জন্য বড় চিত্রগুলিতে 1% নমুনা যথেষ্ট?
জ্যাকথাহিস্টার

জ্যামিতিক মধ্যম মত শোনাচ্ছে। এই সাহায্য করতে পারে? stackoverflow.com/questions/12934213/… এবং আপনি যে পয়েন্টটি সন্ধান করছেন সেটি অবশ্যই মূল সেটে উপস্থিত থাকতে হবে : en.m.wikedia.org/wiki/Medoid#Algorithms_to_compute_medoids
লরেন্স

16

প্রথম: এটি HTML5 ক্যানভাস বা এসভিজি ছাড়াই করা যেতে পারে।
আসলে, কেউ এইমাত্র পরিচালিত জাভাস্ক্রিপ্ট ব্যবহার ক্লায়েন্ট-সাইড PNG ফাইল জেনারেট , ছাড়া ক্যানভাস বা করা SVG ব্যবহার ডেটা URI স্কিম

দ্বিতীয়: আপনার আসলে ক্যানভাস, এসভিজি বা উপরের কোনওটির প্রয়োজন নেই need
আপনি শুধুমাত্র করার প্রয়োজন হলে প্রক্রিয়া , ক্লায়েন্ট পাশ ইমেজ ছাড়া তাদের পরিবর্তন এই সব প্রয়োজন হয় না।

আপনি পৃষ্ঠার ইমগ ট্যাগ থেকে উত্স ঠিকানাটি পেতে পারেন, এর জন্য এক্সএইচআর অনুরোধ করতে পারেন - এটি সম্ভবত ব্রাউজার ক্যাশে থেকে আসে - এবং এটি জাভাস্ক্রিপ্ট থেকে বাইট স্ট্রিম হিসাবে প্রক্রিয়া করে।
আপনার চিত্রের ফর্ম্যাটটি সম্পর্কে ভাল ধারণা দরকার। (উপরের জেনারেটর আংশিকভাবে libpng উত্সের উপর ভিত্তি করে এবং একটি ভাল সূচনা পয়েন্ট সরবরাহ করতে পারে provide)


উপস্থাপন সমাধানের জন্য +1। ক্লায়েন্ট অ্যাপ্লিকেশনটিতে যদি কেবলমাত্র বিকল্পটি তৈরি করা হয় তবে এটি ভাল।
loretoparisi

11

আমি এইচটিএমএল ক্যানভাস ট্যাগ মাধ্যমে বলব।

অপেরা দেব দ্বারা একটি ছোট কোড সম্পর্কে কথা বলার জন্য আপনি এখানে জর্জের একটি পোস্ট পাবেন :

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

এটি প্রতিটি পিক্সেলের আর, জি এবং বি মান ব্যবহার করে চিত্রটি উল্টে দেয়। আপনি খুব সহজেই আরজিবি মানগুলি সংরক্ষণ করতে পারবেন, তারপরে লাল, সবুজ এবং নীল অ্যারেগুলি সংগ্রহ করতে পারেন এবং শেষ পর্যন্ত এটিকে আবার একটি এইচএক্স কোডে রূপান্তর করতে পারেন।


ক্যানভাস সমাধানের কোনও বিকল্প আছে কি?
বিগ্রিটার

@ বেন 4 হিভ: আইই 9 প্ল্যাটফর্মের পূর্বরূপ রয়েছে ;-) তবে গুরুতরভাবে, আমি ভয় করি না।
অ্যান্ডি ই


4

জাভাস্ক্রিপ্টের কোনও চিত্রের পৃথক পিক্সেল রঙের ডেটাতে অ্যাক্সেস নেই। কমপক্ষে, সম্ভবত এইচটিএমএল 5 পর্যন্ত নয় ... এই মুহুর্তে এটি যুক্তিযুক্ত যে আপনি কোনও চিত্র একটি ক্যানভাসে আঁকতে সক্ষম হবেন এবং তারপরে ক্যানভাসটি পরিদর্শন করতে পারবেন (সম্ভবত, আমি নিজে নিজে এটি করি নি)।


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

এটি "কালার কোয়ান্টাইজেশন" সম্পর্কে যা এমএমসিকিউ (পরিবর্তিত মিডিয়ান কাট কোয়ান্টাইজেশন) বা ওকিউ (অ্যাক্ট্রি কোয়ান্টাইজেশন) এর মতো কয়েকটি পদ্ধতির রয়েছে । বিভিন্ন পদ্ধতির রঙের ক্লাস্টারগুলি পেতে কে-মিনস ব্যবহার করে ।

আমি সমস্ত এখানে একসাথে রেখেছি, যেহেতু আমি tvOSযেখানে এক্সএইচটিএমএলের একটি উপসেট রয়েছে তার সমাধান খুঁজে পেয়েছি , যার কোনও <canvas/>উপাদান নেই:

এক্সএমএলএইচটিপিআরকোয়েস্ট সহ আরজিবি চিত্রের জন্য ডমিন্যান্ট রঙগুলি তৈরি করুন


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

একটি অনলাইন সরঞ্জাম পিকমাজেক্লোর ডট কম রয়েছে যা আপনাকে চিত্রের গড় বা প্রভাবশালী রঙ খুঁজে পেতে সহায়তা করে You আপনাকে কেবলমাত্র আপনার কম্পিউটার থেকে একটি চিত্র আপলোড করতে হবে এবং তারপরে চিত্রটিতে ক্লিক করুন। এটি এইচএক্স, আরজিবি এবং এইচএসভিতে গড় রঙ দেয়। এটি চয়ন করতে যে রঙের সাথে মিলছে রঙিন ছায়াগুলিও খুঁজে পেতে পারে। আমি এটি একাধিকবার ব্যবহার করেছি।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.