web-dev-qa-db-ja.com

画像からピクセルのX、Y座標の色を取得する方法は?

PNG画像のselected(x、y)ポイントが透明かどうかを確認する方法はありますか?

112
Danny Fox

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;

1つのピクセルのみを取得するため、pixelDataはピクセルのR、G、B、およびAの値を含む4エントリの配列です。アルファの場合、255未満は透明度を表し、0は完全に透明です。

以下にjsFiddleの例を示します。 http://jsfiddle.net/thirtydot/9SEMf/869/ このすべてで便宜上jQueryを使用しましたが、決して必要ではありません。

注:getImageDataは、データ漏洩を防ぐためのブラウザの同一起源ポリシーに該当します。つまり、キャンバスを別のドメインからの画像、または(私は信じていますが、一部のブラウザはこれを解決しているかもしれません)任意のドメインからのSVG。これにより、サイトがログインしているユーザーのカスタム画像アセットを提供し、攻撃者が画像を読み取って情報を取得したい場合を防ぎます。問題を解決するには、同じサーバーからイメージを提供するか、 Cross-Origin resource sharing を実装します。

184
Brian Nickel

@pstが上記で述べたように、Canvasはこれを行うための素晴らしい方法です。良い例については、この回答をご覧ください。

HTML CanvasからgetPixel?

あなたに特に役立ついくつかのコード:

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の値を取得する必要があります。

17
Jeff Escalante

あり: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);
}
1
A-312

前述の2つの回答は、CanvasとImageDataの使用方法を示しています。実行可能な例と画像処理フレームワークを使用した答えを提案したいので、ピクセルデータを手動で処理する必要はありません。

MarvinJ は、x、y座標のピクセルの透明度値を単に返すメソッドimage.getAlphaComponent(x、y)を提供します。この値が0の場合、ピクセルは完全に透明になり、1〜254の値は透明度レベルになり、最終的に255は不透明になります。

デモのために、透明な背景と座標(0,0)および(150,150)

enter image description here

コンソール出力:

(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>