- PR -

イメージのx,y座標のピクセルの色を取得するには?

1
投稿者投稿内容
maru
ぬし
会議室デビュー日: 2003/01/27
投稿数: 412
投稿日時: 2003-03-07 11:23
いつもお世話になっています。

件名のとおり、イメージのx,y座標のピクセルの色を取得したいのですが、それらしいAPIも
見当たらず、インターネットで調べたところPixelGrabberでint配列に落としたイメージ情報
から色を取得するというサンプルが紹介されていました。
http://homepage2.nifty.com/t-1000/tutorial/java_qanda/q9.html

そのよう処理をしなければ取得できないのでしょうか?
イメージのサイズも結構大きいのですが、いつ、どれくらいの頻度で呼び出されるかわから
ない色取得の処理にそのような処理をしてしまうととてつもなくメモリを消費されてしまう
のであまりよろしくありません。

ご存知の方おられませんか?
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2003-03-07 11:48
unibon です。こんにちわ。

引用:

maruさんの書き込み (2003-03-07 11:23) より:
イメージのサイズも結構大きいのですが、いつ、どれくらいの頻度で呼び出されるかわから
ない色取得の処理にそのような処理をしてしまうととてつもなくメモリを消費されてしまう
のであまりよろしくありません。


PixelGrabber は grab する領域の大きさを指定できますので、
1ピクセル(横1かける縦1)の領域を指定して grab するのなら、
それほど負荷は高くないと想像します(定量的な判断ではないですが)。

また、Java2D になりますが、
BufferedImage クラスに getRGB メソッドがあるので、
これを使っても色を調べることはできます。
http://java.sun.com/j2se/1.4/ja/docs/ja/api/java/awt/image/BufferedImage.html#getRGB(int, int)
maru
ぬし
会議室デビュー日: 2003/01/27
投稿数: 412
投稿日時: 2003-03-07 21:01
こんばんは。
BufferedImageクラスを見落としていました。getRGBが使えますね。
ありがとうございました。

しかし、javaのグラフィックライブラリはJAIやJIMIやImageIOなどなどいろいろあって、
結局JDK1.4からImageIOに落ち着いたようですが、バグがあったり情報少なかったりで
しんどいですね・・・(グチ)。


maru
ぬし
会議室デビュー日: 2003/01/27
投稿数: 412
投稿日時: 2003-03-10 13:43
こんにちは。

BufferedImageのgetRGBを使おうとしました。しかし、使っているのはImageクラスだった
ので、(BufferedImage)Image とキャストしようとしたのですが、コンパイルはできるので
すが、実行時にClassCastExceptionでキャストできないと怒られました。ダウンキャスト
(ナローイング変換)でできないのかな?
冷静に考えるとあたりまえのような気はするが・・・。

http://homepage1.nifty.com/masada/cyber/javajpeg.htm
にはキャストできないから作業用のBufferedImageからGraphicsをとりだして、Image
オブジェクトを貼り付けるというようなやり方でやっています。こんな方法しかないので
しょうか?

だめならPixelGrabberでやろうと思うのですが、1点のピクセルと、2点の矩形範囲の複数
ピクセルならPixelGrabberでもいいのですが、2点間の線上の(複数の)ピクセルも取得
したいのですが、1点取得するロジックをループでまわせばいいことですが、あまりきれい
な処理ではないと思いました。

何か良い方法をご存知の方おられませんでしょうか?

しかし、なんでGraphicsからGraphics2Dへのダウンキャストができるのに、Imageから
BufferedImageへのダウンキャストはできないのだろう???


[ メッセージ編集済み 編集者: maru 編集日時 2003-03-10 13:43 ]
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2003-03-10 14:08
unibon です。こんにちわ。

すみません。前回、書き漏らしたのですが、getRGB を使うためには、
「もし BufferedImage を使っている(あるいは使って良い)のならば」、
という前提条件が抜けていました。
BufferedImage extends Image なので運が良ければ、
Image 型の変数で持っているものを実行時に BufferedImage にキャストして使えますが、
普通はできないし、もしできたとしても Image の出所が異なれば、
実行時にキャストできないこともあるので、やらないほうが無難でしょう。
ちなみに現在はどのようにして Image 型のインスタンスを
得られているのでしょうか。

引用:

maruさんの書き込み (2003-03-10 13:43) より:
だめならPixelGrabberでやろうと思うのですが、1点のピクセルと、2点の矩形範囲の複数
ピクセルならPixelGrabberでもいいのですが、2点間の線上の(複数の)ピクセルも取得
したいのですが、1点取得するロジックをループでまわせばいいことですが、あまりきれい
な処理ではないと思いました。


かなり揚げ足取りになりますが、
線上のピクセルを取得するという要求自体が、
あまりきれいではないような気もします。
あと、やりかたとして思いつくのは、
線分を囲む Rectangle を PixelGrabber の範囲に指定することですが、
でも、線分が長いと面積が大きくなるので、負荷はかかりそうですね。

ただ、色を調べるには PixelGrabber か BufferedImage.getRGB の
いずれかしかないと思います。
maru
ぬし
会議室デビュー日: 2003/01/27
投稿数: 412
投稿日時: 2003-03-10 14:48
こんにちは。返答ありがとうございます。

>ちなみに現在はどのようにして Image 型のインスタンスを
>得られているのでしょうか。
いろいろなパターンでイメージ化しているのですが、一番大きな処理のひとつとして、
int配列からMemoryImageSourceに変換して、Toolkit の createImage を使って
イメージにしています。createImage の戻値はImage型になっていました。

場合によっては、コンポーネントの ImageIcon からgetImageで取得する場合もあり、
それも戻値はImage型になっていました。

なので、BufferedImage は使えそうにないので、PixelGrabberでいくしかなさそうですね?

>線上のピクセルを取得するという要求自体が、
>あまりきれいではないような気もします。
そうかなぁ?画像処理ソフトなどでよく(?)あるように、指定した2点の座標間の直線上
のピクセルの輝度をグラフで表示したいのです。
int配列を渡すとグラフ表示するコンポーネントはできているので、あとは、指定した2点
の座標間の直線上のピクセルの色をint配列に落とし込んで渡すだけです。
そのために、x,y座標のピクセルの色を取得したいのですが・・・。

やりたいことはつまらないことなんですが、javaでやろうとすると結構大変ですねぇ・・・。
いくらグラフィック関連APIはハードウェアに依存されているから抽象化されてると言っても、
線を書く命令があって座標の色を取得する命令がないのは理解できないなぁ。
なんでだろぉ〜???

[ メッセージ編集済み 編集者: maru 編集日時 2003-03-10 14:57 ]
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2003-03-10 15:11
unibon です。こんにちわ。

引用:

maruさんの書き込み (2003-03-10 14:48) より:
なので、BufferedImage は使えそうにないので、PixelGrabberでいくしかなさそうですね?


はい。そう思います。

引用:

maruさんの書き込み (2003-03-10 14:48) より:
>線上のピクセルを取得するという要求自体が、
>あまりきれいではないような気もします。
そうかなぁ?画像処理ソフトなどでよく(?)あるように、指定した2点の座標間の直線上
のピクセルの輝度をグラフで表示したいのです。


すみません。ちょっと憶測まじりで
ドロー系のアプリケーションを勝手に想像していました。
たしかに、ペイント系のアプリケーションで
そのものズバリの機能の実現のためなら必要ですよね。

引用:

maruさんの書き込み (2003-03-10 14:48) より:
いくらグラフィック関連APIはハードウェアに依存されているから抽象化されてると言っても、
線を書く命令があって座標の色を取得する命令がないのは理解できないなぁ。
なんでだろぉ〜???

[ メッセージ編集済み 編集者: maru 編集日時 2003-03-10 14:57 ]


Graphics(や Graphics2D) には色の取得がなくても良いと思います。
たとえば、プリンタなどピクセルの概念が薄いものだと、
ピクセルを指定することがそもそもできませんし。
ちなみに Graphics クラスには点を描くメソッドもないですよね。
そういうことから PixelGrabber や Image(BufferedImage) が担うのは妥当だと思います。

#でも Windows API だと GDI に SetPixel や GetPixel があったなあ。
maru
ぬし
会議室デビュー日: 2003/01/27
投稿数: 412
投稿日時: 2003-03-10 15:51
こんにちは。
>Graphics(や Graphics2D) には色の取得がなくても良いと思います。
>たとえば、プリンタなどピクセルの概念が薄いものだと、
>ピクセルを指定することがそもそもできませんし。
>ちなみに Graphics クラスには点を描くメソッドもないですよね。
>そういうことから PixelGrabber や Image(BufferedImage) が担うのは妥当だと
>思います。
う〜ん。確かに点を描くメソッドはないですねぇ。”ピクセル”という概念が薄いもの
もあるからというのは分かるのですが、”ピクセル”という点の長さ(大きさ)の概念
は薄くても、線や円を描くのと同様に、点を描くという概念はあってもいいと思うので
すが・・・???

お絵かきソフトのブラシでランダムに点を描いたり、星や花火なんかの点を描画するよう
なアプリは java では点ではなく、線で点のように描画するということになりますねぇ。

まっ、そんなものだと今は理解しようと思いますが、なんかしっくりこないのは私だけ?

1

スキルアップ/キャリアアップ(JOB@IT)