2012-01-05 250 views
90

是否有任何方法檢查PNG圖像的選定(x,y)點是否透明?如何從圖像中獲取像素的x,y座標顏色?

+1

可以將圖像以某種方式被加載在畫布元素上? – 2012-01-05 22:50:54

+0

如果沒有其他方法,那麼 – 2012-01-05 22:51:46

+2

這就是必須完成的。 – 2012-01-05 22:53:43

回答

149

基於Jeff的回答,您的第一步是創建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.offsetXevent.offsetY得到的位置。這可以被用於獲取像素:

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

因爲僅抓住一個像素,PixelData取出是包含該像素的R,G,B和A的值的四個條目數組。對於alpha,任何小於255的值都代表某種透明度,0是完全透明的。

這裏是一個jsFiddle的例子:http://jsfiddle.net/thirtydot/9SEMf/869/我在所有這些方面都使用了jQuery,但它絕不是必需的。

注意:如果髒從另一個域或(我相信圖像畫布getImageData瀑布瀏覽器的同源策略下,以防止數據泄露,這意味着這種技術將會失敗,但有些瀏覽器可能已經解決了這個)來自任何域的SVG。這樣可以防止站點爲登錄用戶提供自定義圖像資源,攻擊者想要讀取圖像以獲取信息。您可以通過從相同服務器提供映像或實施Cross-origin resource sharing來解決問題。

+2

繁榮 - 令人敬畏的工作。我知道我應該像這樣做一個小提琴,但是太胖了,太懶了。你在這裏殺了它 – 2012-01-10 00:03:17

+0

爲了正確,你需要設置畫布的座標空間,即設置寬度和高度以匹配圖像尺寸。 CSS寬度和高度僅用於拉伸佈局的最終​​畫布,當它是未顯示的元素時無法幫助。試試類似$('');.或者這種方式不適用於屏幕外的畫布? – fabspro 2012-12-12 14:13:02

+0

@fabspro:這是一個很好的觀點。由於通過上下文繪製和讀取圖像數據,寬度和高度值是沒有意義的。他們沒有任何不良影響,因爲畫布不是上下文扭曲的原因,我沒有看到這種影響我的演示,只是因爲圖像比上下文的初始寬度/高度小。我會相應地進行更新,儘管在畫布本身上訪問'.width'和'.height'比連接更安全。 – 2012-12-14 21:20:17

15

畫布將是一個偉大的方式來做到這一點,正如@pst上面所說。看看這個答案的一個很好的例子:

getPixel from 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的click事件輕鬆完成。只需在點擊處理程序內部運行上述代碼即可:

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

那些應該抓住您的x和y值。

0

以前的兩個答案演示瞭如何使用Canvas和ImageData。我想提出一個可運行示例並使用圖像處理框架的答案,因此您不需要手動處理像素數據。

MarvinJ提供了方法image.getAlphaComponent(x,y)它只是返回像素在x,y座標中的透明度值。如果此值爲0,則像素是完全透明的,1到254之間的值是透明度級別,最後255是不透明的。

對於具有透明背景,並在座標(0,0)(150150)兩個像素證明我用下面(300×300)圖像。

enter image description here

控制檯輸出:

(0,0):透明
(150150):NOT_TRANSPARENT

var canvas = document.getElementById("canvas"); 
 
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> 
 
<canvas id="canvas" width="500" height="344"></canvas>