Не впевнений, що це можливо, але прагнучи написати сценарій, який би повернув середнє значення hex
rgb
значення або значення для зображення. Я знаю, що це можна зробити в AS, але хочу зробити це в JavaScript.
Не впевнений, що це можливо, але прагнучи написати сценарій, який би повернув середнє значення hex
rgb
значення або значення для зображення. Я знаю, що це можна зробити в AS, але хочу зробити це в JavaScript.
Відповіді:
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 ознайомтеся з есканвами .
'rgb('+rgb.r+','+rgb.b+','+rgb.g+')'
і це повинно бути 'rgb('+rgb.r+','+rgb.g+','+rgb.b+')'
. дивно, коли домінуючий колір синій, але результат - зелений :).
img.crossOrigin = '';
перш ніж встановлювати src
атрибут. Знайдено на: coderwall.com/p/pa-2uw
count === length / 4 / blockSize
;)
Подумав, що я опублікував проект, який я нещодавно зіткнувся, щоб отримати домінуючий колір
Сценарій захоплення домінуючого кольору або репрезентативної кольорової палітри зображення. Використовує javascript та полотно.
Інші рішення, що згадують та пропонують домінуючий колір, ніколи насправді не відповідають на питання у відповідному контексті ("у javascript"). Сподіваємось, цей проект допоможе тим, хто хоче зробити саме це.
"Домінантний колір" хитрий. Що ви хочете зробити, це порівняти відстань між кожним пікселем та кожним іншим пікселем у кольоровому просторі (евклідова відстань), а потім знайти піксель, колір якого найближчий до кожного іншого кольору. Цей піксель є домінуючим кольором. Середній колір зазвичай буде грязюкою.
Я б хотів, щоб я мав тут MathML, щоб показати вам евклідову відстань. Google це.
Я виконав вищезазначене виконання в кольоровому просторі RGB, використовуючи PHP / GD тут: https://gist.github.com/cf23f8bddb307ad4abd8
Однак це обчислювально дуже дорого. Це призведе до краху вашої системи на великих зображеннях і, безумовно, збій вашого веб-переглядача, якщо ви спробуєте його у клієнті. Я працюю над рефакторингом мого виконання, щоб: - зберігати результати в таблиці пошуку для подальшого використання в ітерації над кожним пікселем. - розділити великі зображення на сітки 20px 20px для локалізованого домінування. - використовувати евклідову відстань між x1y1 та x1y2, щоб визначити відстань між x1y1 та x1y3.
Будь ласка, дайте мені знати, якщо ви прогресуєте на цьому фронті. Я був би радий це бачити. Я зроблю те саме.
Полотно, безумовно, найкращий спосіб зробити це у клієнта. SVG не є, SVG - векторною. Після того, як я знижую виконання, наступне, що я хочу зробити, - це запустити це на полотні (можливо, з веб-роботою для загального розрахунку відстані кожного пікселя).
Інша річ, про яку слід подумати, - це те, що RGB не є хорошим кольоровим простором для цього, оскільки евклідова відстань між кольорами в просторі RGB не дуже близька до зорової відстані. Кращий колірний простір для цього може бути LUV, але я не знайшов для цього гарної бібліотеки або будь-яких алгоритмів для перетворення RGB в LUV.
Зовсім інший підхід полягає в сортуванні кольорів за веселкою та побудові гістограми з толерантністю для врахування різних відтінків кольору. Я цього не пробував, тому що сортувати кольори в веселці важко, так само як і кольорові гістограми. Я можу спробувати це далі. Знову, дайте мені знати, якщо ви досягнете будь-якого прогресу тут.
По-перше: це можна зробити без HTML5 Canvas або SVG.
Насправді, хтось просто зумів генерувати файли PNG на стороні клієнта за допомогою JavaScript , без полотна або SVG, використовуючи схему URI даних .
По-друге: вам може взагалі не знадобитися Canvas, SVG або будь-яке з перерахованого вище.
Якщо вам потрібно лише обробляти зображення на стороні клієнта, не змінюючи їх, все це не потрібно.
Ви можете отримати адресу джерела з тегу img на сторінці, зробити XHR запит на нього - він, швидше за все, буде надходити з кешу браузера - та обробити його як потік байтів з Javascript.
Вам буде потрібно добре розуміти формат зображення. (Вищенаведений генератор частково базується на джерелах libpng і може стати гарною відправною точкою.)
Я б сказав через тег HTML canvas.
Ви можете знайти тут повідомлення від @Georg, що розповідає про невеликий код програми Opera:
// 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.
Нещодавно я натрапив на плагін jQuery, який робить те, що я спочатку хотів https://github.com/briangonzalez/jquery.adaptive-backgrounds.js щодо отримання домінуючого кольору з зображення.
Javascript не має доступу до окремих кольорових даних пікселів зображення. Принаймні, не може, поки не буде html5 ... в цей момент, без сумніву, ви зможете намалювати зображення на полотні, а потім оглянути полотно (можливо, я цього ніколи не робив сам).
Я б особисто поєднав Color Thief разом із цією модифікованою версією Name the Color щоб отримати більш ніж достатній масив домінуючих результатів кольорів для зображень.
Приклад:
Розглянемо наступне зображення:
Ви можете використовувати наступний код для отримання даних про зображення, що стосуються домінуючого кольору:
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;
Йдеться про "квантування кольорів", яке має декілька підходів, як MMCQ (модифікована середня квантованість медіану) або OQ (квантування жовтня). Інший підхід використовує K-засоби для отримання скупчень кольорів.
Я все це склав тут, оскільки я знаходив рішення для того, tvOS
де є підмножина XHTML, яка не має<canvas/>
елемента:
Створіть домінуючі кольори для зображення RGB за допомогою XMLHttpRequest
Менш точний, але найшвидший спосіб отримати середній колір зображення з 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);
}
Існує інтернет-інструмент pickimagecolor.com, який допоможе вам знайти середній або домінуючий колір зображення. Вам просто потрібно завантажити зображення зі свого комп'ютера, а потім натиснути на зображення. Він дає середній колір у HEX, RGB та HSV. Він також знаходить кольорові відтінки, які відповідають цьому кольорові на вибір. Я використовував його кілька разів.