Як отримати колір координати x, y пікселя з зображення?


124

Чи є спосіб перевірити, чи вибрана (x, y) точка зображення PNG прозора?


1
Чи можна якось завантажити зображення на елемент Canvas?

Якщо іншого шляху немає, то
Danny Fox

Відповіді:


199

Спираючись на відповідь Джеффа, вашим першим кроком було б створити зображення на полотні вашої PNG. Далі створюється позаекранне полотно, яке має таку саму ширину та висоту, як і ваше зображення, і на ньому зображено зображення.

var img = document.getElementById('my-image');
var canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height);

Після цього, коли користувач натискає, використовуйте event.offsetXта event.offsetYотримуйте позицію. Потім це можна використовувати для отримання пікселя:

var pixelData = canvas.getContext('2d').getImageData(event.offsetX, event.offsetY, 1, 1).data;

Оскільки ви захоплюєте лише один піксель, pixelData - це чотири вхідні масиви, що містять значення R, G, B та A пікселя. Для альфа все, що менше 255, означає деякий рівень прозорості, а 0 - повністю прозорий.

Ось приклад jsFiddle: http://jsfiddle.net/thirtydot/9SEMf/869/ Я використовував jQuery для зручності у всьому цьому, але це ні в якому разі не потрібно.

Примітка: getImageData підпадає під політику веб-переглядача одного веб-переглядача, щоб запобігти витоку даних, тобто ця методика не вдасться, якщо ви забруднили полотно зображенням із іншого домену або (я вважаю, але деякі браузери, можливо, вирішили це) SVG з будь-якого домену. Це захищає від випадків, коли сайт обслуговує користувальницький ресурс зображення для користувача, який увійшов у систему, а зловмисник хоче прочитати зображення для отримання інформації. Вирішити проблему можна, обслуговуючи зображення з того самого сервера або застосувавши спільний доступ до ресурсів .


3
бум - дивовижна робота. Я знав, що я повинен був зробити такий загадку, але був занадто жирним і ледачим. ви вбили його тут
Джефф Ескаланте

Щоб це було правильно, вам потрібно встановити координатний простір полотна, тобто встановити ширину та висоту відповідно до розмірів зображення. Ширина та висота CSS служать лише для розтягування остаточного полотна для компонування, що не допомагає, коли це не відображений елемент. Спробуйте щось на зразок $ ('<canvas width =' + img.width + 'height =' + img.height + '/>') ;. Або це якось не стосується полотна поза екраном?
fabspro

@fabspro: Це прекрасний момент. Оскільки малювання та читання даних зображення здійснюються через контекст, значення ширини та висоти є безглуздими. Вони не мають жодного поганого ефекту, тому що полотно, а не контекст, є викривленим, і тому, що я не бачив цього ефекту на моєму демонструванні, просто тому, що зображення менше початкової ширини / висоти контексту. Я відповідно оновлю, хоча це безпечніше для доступу .widthта .heightна самому полотні, ніж шляхом конкатенації.
Брайан Нікель

4
Виправити це для Firefox jsfiddle.net/9SEMf/622 з допомогою цього stackoverflow.com/questions/11334452/event-offsetx-in-firefox
Benoit

6
Ви не можете використовувати це для віддалених зображень. "Неможливо отримати дані зображення з полотна, тому що полотно було пошкоджено даними перехресного походження. SecurityError: Була зроблена спроба прорватися через політику безпеки агента користувача."
Карл Глазер

18

Полотно було б чудовим способом зробити це, як @pst сказав вище. Ознайомтеся з цією відповіддю як хороший приклад:

getPixel з HTML Canvas?

Деякі коди, які також вам точно послужать:

var imgd = context.getImageData(x, y, width, height);
var pix = imgd.data;

for (var i = 0, n = pix.length; i < n; i += 4) {
  console.log pix[i+3]
}

Це буде йти рядок за рядком, тому вам потрібно буде перетворити це в x, y і або перетворити цикл for в пряму перевірку, або виконати умовне всередині.

Прочитавши ще раз своє запитання, схоже, ви хочете отримати можливість отримати точку, на яку людина натискає. Це можна зробити досить легко за допомогою події клацання jquery. Просто запустіть наведений вище код в обробці кліків як такому:

$('el').click(function(e){
   console.log(e.clientX, e.clientY)
}

Вони повинні захоплювати ваші значення x та y.


Це не те, що запитав коментатор (здавалося б), і зовсім не відповідає на питання. Прийнята відповідь спрацює. Рекомендую видалити цю відповідь ...
Агамемнус

5

Два попередні відповіді демонструють, як користуватися Canvas та ImageData. Я хотів би запропонувати відповідь із прикладом запуску та використанням рамки обробки зображень, тому вам не потрібно обробляти дані пікселів вручну.

MarvinJ надає метод image.getAlphaComponent (x, y) який просто повертає значення прозорості пікселя у координаті x, y. Якщо це значення дорівнює 0, піксель повністю прозорий, значення від 1 до 254 - рівні прозорості, нарешті, 255 непрозорі.

Для демонстрації я використав зображення нижче (300x300) з прозорим фоном та двома пікселями за координатами (0,0) та (150,150) .

введіть тут опис зображення

Вихід консолі:

(0,0):
ПРОЗРАЧНИЙ (150,150): NOT_TRANSPARENT

image = new MarvinImage();
image.load("https://i.imgur.com/eLZVbQG.png", imageLoaded);

function imageLoaded(){
  console.log("(0,0): "+(image.getAlphaComponent(0,0) > 0 ? "NOT_TRANSPARENT" : "TRANSPARENT"));
  console.log("(150,150): "+(image.getAlphaComponent(150,150) > 0 ? "NOT_TRANSPARENT" : "TRANSPARENT"));
}
<script src="https://www.marvinj.org/releases/marvinj-0.7.js"></script>


2

З: i << 2

const data = context.getImageData(x, y, width, height).data;
const pixels = [];

for (let i = 0, dx = 0; dx < data.length; i++, dx = i << 2) {
    if (data[dx+3] <= 8)
        console.log("transparent x= " + i);
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.