Bir görüntüden pikselin x, y koordinat rengi nasıl elde edilir?


124

PNG görüntüsünün seçili (x, y) noktasının şeffaf olup olmadığını kontrol etmenin bir yolu var mı?


1
Görüntü bir şekilde bir Canvas öğesine yüklenebilir mi?

Başka bir yol yoksa, o zaman
Danny Fox

Yanıtlar:


199

Jeff'in cevabına dayanarak, ilk adımınız PNG'nizin kanvas temsilini oluşturmak olacaktır. Aşağıdakiler, görüntünüzle aynı genişlik ve yükseklikte olan ve görüntünün üzerine çizildiği ekran dışı bir tuval oluşturur.

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

Bundan sonra, bir kullanıcı tıkladığında, konumu almak için event.offsetXve tuşlarını kullanın event.offsetY. Bu, daha sonra pikseli elde etmek için kullanılabilir:

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

Yalnızca bir pikseli yakaladığınız için pixelData, pikselin R, G, B ve A değerlerini içeren dört girişli bir dizidir. Alfa için 255'ten az olan herhangi bir şey, 0'ın tamamen şeffaf olduğu bir miktar şeffaflık düzeyini temsil eder.

İşte bir jsFiddle örneği: http://jsfiddle.net/thirtydot/9SEMf/869/ Tüm bunlarda kolaylık olması için jQuery kullandım, ancak hiçbir şekilde gerekli değil.

Not: getImageData veri sızıntılarını önlemek için tarayıcının aynı menşe politikası kapsamına girer; bu, tuvali başka bir etki alanından bir görüntüyle veya (sanırım bazı tarayıcılar bunu çözmüş olabilir) herhangi bir etki alanından SVG ile kirlettiğinizde bu tekniğin başarısız olacağı anlamına gelir. Bu, bir sitenin oturum açmış bir kullanıcı için özel bir görüntü varlığı sunduğu ve bir saldırganın bilgi almak için görüntüyü okumak istediği durumlara karşı koruma sağlar. Görüntüyü aynı sunucudan sunarak veya Çapraz kaynaklı kaynak paylaşımını uygulayarak sorunu çözebilirsiniz .


3
patlama - harika iş. Böyle bir keman yapmam gerektiğini biliyordum ama çok şişman ve tembeldim. onu burada öldürdün
Jeff Escalante

Bunun doğru olması için, tuvalin koordinat alanını ayarlamanız, yani genişliği ve yüksekliği görüntü boyutlarıyla eşleşecek şekilde ayarlamanız gerekir. CSS genişliği ve yüksekliği, yalnızca mizanpaj için son tuvali uzatmaya yarar; bu, görüntülenmemiş bir öğe olduğunda yardımcı olmaz. $ ('<Canvas width =' + img.width + 'height =' + img.height + '/>'); gibi bir şey deneyin. Yoksa bu bir şekilde ekran dışı tuvaller için geçerli değil mi?
fabspro

@fabspro: Bu mükemmel bir nokta. Görüntü verilerinin çizilmesi ve okunması bağlam üzerinden yapıldığı için genişlik ve yükseklik değerleri anlamsızdır. Herhangi bir kötü etkisi yoktur çünkü bağlam değil tuval çarpıtılır ve demomda bu etkiyi görmememin nedeni, görüntünün bağlamın başlangıçtaki genişliğinden / yüksekliğinden daha küçük olmasıdır. Buna göre güncelleme yapacağım, ancak tuvale erişmek .widthve .heightbirleştirme işleminden daha güvenli .
Brian Nickel


6
Bunu uzak görüntüler için kullanamazsınız. "Tuval, çapraz kaynak verileriyle bozulduğu için tuvalden görüntü verileri alınamıyor. SecurityError: Kullanıcı aracısının güvenlik politikasını aşmak için bir girişimde bulunuldu."
Karl Glaser

18

@Pst'nin yukarıda söylediği gibi canvas bunu yapmanın harika bir yolu olabilir. İyi bir örnek için bu cevaba göz atın:

HTML Canvas'tan getPixel?

Size özel olarak da hizmet edecek bazı kodlar:

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]
}

Bu satır satır gidecek, bu yüzden bunu bir x, y'ye dönüştürmeniz ve for döngüsünü doğrudan bir kontrole dönüştürmeniz veya içinde bir koşullu çalıştırmanız gerekir.

Sorunuzu tekrar okuduğunuzda, o kişinin tıkladığı noktayı elde edebilmek istiyorsunuz gibi görünüyor. Bu, jquery'nin tıklama olayı ile oldukça kolay bir şekilde yapılabilir. Yukarıdaki kodu bir tıklama işleyicisinin içinde çalıştırmanız yeterlidir:

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

Bunlar sizin x ve y değerlerinizi almalı.


Bu, yorumcunun sorduğu şey değil (görünüşte) ve soruya hiç cevap vermiyor. Kabul edilen cevap işe yarıyor. Bu yanıtı silmenizi tavsiye ederim ...
Agamemnus

5

Önceki iki cevap, Canvas ve ImageData'nın nasıl kullanılacağını göstermektedir. Piksel verilerini manuel olarak işlemenize gerek kalmaması için çalıştırılabilir bir örnekle ve bir görüntü işleme çerçevesi kullanarak bir cevap önermek istiyorum.

MarvinJ , x, y koordinatındaki piksel için şeffaflık değerini basitçe döndüren image.getAlphaComponent (x, y) yöntemini sağlar . Bu değer 0 ise, piksel tamamen şeffaftır, 1 ile 254 arasındaki değerler şeffaflık seviyeleridir ve son olarak 255 opaktır.

Göstermek için aşağıdaki görüntüyü (300x300) şeffaf arka plan ve (0,0) ve (150,150) koordinatlarında iki piksel kullandım .

görüntü açıklamasını buraya girin

Konsol çıkışı:

(0,0): ŞEFFAF
(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>


1

İle : 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);
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.