- PR -

画像を淡くし背景が透き通らない描画をするには

投稿者投稿内容
takka
会議室デビュー日: 2004/08/24
投稿数: 7
投稿日時: 2006-11-11 11:34
画像を淡くし背景が透き通らない描画をしたいのですが、どうすればよいでしょうか。基本的にAlphaCompositeを使おうと思っています。Javaは1.4です。

実践して失敗した例を示します。
(1)透明化で描画
 方法:
@AlphaCompositeを使って描画
 問題点:
 背景が透き通ってしまう
(2)描画範囲を一回白で描画して透明化で描画
 方法:
 @描画範囲を指定しcreateimageでImage作成
 A@のImageを白くして描画
 B目的の画像を透明化して描画
 問題点:
 白で描画するのは四角しか出来ず、目的の画像が四角でない場合、背景が消えてしまう部分がある。
(3)目的の画像と同じ描画範囲で背景を塗りつぶした後、透明化で描画
 方法:
 @createImageで目的の画像と同じImageを作成する。
 A@のImageを白で塗りつぶす
 問題点:
 ImageにGraphicsがないため、塗りつぶせない
nekoyama
ベテラン
会議室デビュー日: 2005/03/12
投稿数: 71
投稿日時: 2006-11-11 16:10
何に対して描画しようとしているかわかりません。

JComponentに描画するのであれば、setOpaque(boolean)は設定していますか。

それとも、イメージ自体をぼかしたいのですか?
takka
会議室デビュー日: 2004/08/24
投稿数: 7
投稿日時: 2006-11-11 21:57
描画物はjava.awt.Imageです。
描画対象はComponentです。swingは使用しておりません。
ひら
ぬし
会議室デビュー日: 2005/03/04
投稿数: 260
投稿日時: 2006-11-11 23:12
私は(2)と手順は逆でImageの上に半透明の白をかぶせる方法で実現したことがあります。
やはり背景が消えてしまうという問題が残ったままでしたが、そもそも四角い画像しか
なかったためなんとかなりました。
四角でない画像の場合ですが、そのような図形に合う形のfillPolygonの白で被せる
というのはどうでしょうか?

unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2006-11-12 00:04
引用:

takkaさんの書き込み (2006-11-11 11:34) より:
(3)目的の画像と同じ描画範囲で背景を塗りつぶした後、透明化で描画


引用:

takkaさんの書き込み (2006-11-11 11:34) より:
 問題点:
 ImageにGraphicsがないため、塗りつぶせない


#丸付き数字はいわゆる機種依存文字なので使われないほうが良いです。

Image の getGraphics は使えないでしょうか?
http://sdc.sun.co.jp/java/docs/j2se/1.4/ja/docs/ja/api/java/awt/Image.html#getGraphics()
Image の実行時クラスにもよりますが。

--
unibon {B73D0144-CD2A-11DA-8E06-0050DA15BC86}
nekoyama
ベテラン
会議室デビュー日: 2005/03/12
投稿数: 71
投稿日時: 2006-11-12 02:27
引用:

(1)透明化で描画
 方法:
@AlphaCompositeを使って描画
 問題点:
 背景が透き通ってしまう


描画対象がjava.awt.Componentで、java.awt.Compositeを使用するということは、
AWTのpaint系メソッドで使用されているGraphicsインスタンスが
実際は、Graphics2Dインスタンスであると知っていて、
GraphicsをGraphics2Dにキャストしたあとに、Graphics2D.setComposite()を使用する
ということですよね?

ということであれば、設定したComposite自体を元に戻していないのでは?
と推測します。
インデントの入れ方が分からないので、見難いかもしれませんが、
コードがこんな感じになっていませんか?

(誤)
public void paint(Graphics g){
Graphics2D g2d = (Graphics2D)g;
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f));
//イメージを描画
//背景を描画したりsuper.paint();
}
(正)
public void paint(Graphics g){
Graphics2D g2d = (Graphics2D)g;
Composite oldComp = g2d.getComposite();
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f));
//イメージを描画
g2d.setComposite(oldComposite);
//背景を描画したりsuper.paint();
}
上のコードで、イメージや背景の描画記述位置はどうでもいいのですが、
要は、一度設定したCompositeを元のCompositeに戻していますか?ということです。
Compositeを元に戻さないと、イメージも背景も同じアルファで描画されるので、
そんなところでは?と思いました。

ちなみに、Imageですが、java.awt.Imageでしょうか?
どうしても、java.awt.Imageである必要があるのですか?
それと、Imageはイメージファイル等の外部リソースを読み込んだものですか?
それとも自前で描画しているイメージでしょうか。

うーん、投稿にどうやって、インデントを入れるのだろうか。。。
takka
会議室デビュー日: 2004/08/24
投稿数: 7
投稿日時: 2006-11-12 12:53
回答ありがとうございます。
また、質問内容があいまいですみません。

ファイルから取ってきた画像でImageオブジェクト(ImageA)を作成し、あるComponentにImageAを描画したいです。このときImageAを淡くして表示したいです。

> 四角でない画像の場合ですが、そのような図形に合う形のfillPolygonの白で被せる
> というのはどうでしょうか?
この場合、ImageAからfillPolygonを取得する必要があり、難しいです。

> #丸付き数字はいわゆる機種依存文字なので使われないほうが良いです。
拝承です。

> Image の getGraphics は使えないでしょうか?
できないようです。以下で作成したImageDummyにgetGraphicsがなく、例外がでてきました。
Image ImageA = createImage(ファイル名);
Image ImageDummy = createImage(ImageA.getSource);

> Compositeを元に戻さないと、イメージも背景も同じアルファで描画されるので、
> そんなところでは?と思いました。
背景を描画して、そこにイメージを描画しています。そのため背景が透き通ってしまいます。

> どうしても、java.awt.Imageである必要があるのですか?
Imageを基本としているため、Imageがよいです。

> それと、Imageはイメージファイル等の外部リソースを読み込んだものですか?
そのとおりです
nekoyama
ベテラン
会議室デビュー日: 2005/03/12
投稿数: 71
投稿日時: 2006-11-12 16:14
実現したいイメージ等が実際には分かりませんが、
(Web上とかで実現したい状態のサンプルとかありますか?)
今回の場合、イメージ自体をフィルタする必要はなさそうなので、
ポイントは3つだと思います。

1.背景とイメージの描画順
2.clip(java.awt.Shape)の適切な設定(上記、描画順に合わせたclipの設定)
#java.awt.Shapeとその実装クラスを調べましょう。
3.前述したようにAlphaCompositeを適切に使用すること

引用:

背景を描画して、そこにイメージを描画しています。そのため背景が透き通ってしまいます。


上述のとおり、背景とイメージの描画順を変更してください。

で、まえに書きましたが、AlphaCompositeは元に戻していますか?

引用:

ImageAからfillPolygonを取得する


引用:

したImageDummyにgetGraphicsがなく、例外がでてきました。


とか、やってることの意味が分からないんですが。

引用:

> どうしても、java.awt.Imageである必要があるのですか?
Imageを基本としているため、Imageがよいです。


予断ですがJava1.4ならば、JAIではなく、ImageIOフレームワークが導入されているので、jpegとかを外部から読み込むんであれば、ImageIOフレームワークで
java.awt.image.BufferedImageで読み込んだ方が、イメージのロード、セーブも
操作も楽だし今後も応用がききます。
別に今回の場合、BufferedImageでもjava.awt.Imageでも良いですが。

BufferedImageも、java.awt.Imageインスタンスなので、
読み込んだBufferedImageをjava.awt.Imageインスタンスとして扱えばいいわけですし。

可能であれば、ミニマムコードを示した方が良いです。

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