- PR -

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

投稿者投稿内容
nekoyama
ベテラン
会議室デビュー日: 2005/03/12
投稿数: 71
投稿日時: 2006-11-12 16:48
余談です。
java.awt.Graphic2Dを使用せず、java.awt.Graphicsしか使えない、
または使わないという前提があるならば、下記は参考までに。

今でも、1990年代にAppletを使用していた頃に書かれたんだろうなと
思うようなコードには、drawLine(),drawPolygon()とかを散見しますが、
Graphic2Dを使用する場合、GraphicsクラスのdrawLine(),fillPolygon(),
fillRect()とかは、使用しないほうが良いです。

理由は、Shapeを変更すれば、すぐに描画内容を変更できるコードができるため、
メンテナンスも楽になるし、拡張性も高くなるためです。
では、代わりに何を使用するかといえば、上記メソッドの代わりに、draw(java.awt.Shape),fill(java.awt.Shape)を使用します。

#描画処理のために、一々Shapeオブジェクトを生成したくないとか、
#メンテナンスや拡張性より今すぐ動くものが欲しいとの刹那的発想や
#Shapeオブジェクトを生成するのがメンドクサイなら話は別ですが。

これは、オブジェクト指向の多態性を理解していれば、理由は分かるでしょう。

同様に、Graphics#setClip(int, int, int, int)や、Graphics#setColor(java.awt.Color)も使用しないほうが良いです。

理由は前述のとおり、メンテナンスと拡張性のためです。
代わりに、Graphics#setClip(Shape),Graphics2D.setPaint(java.awt.Paint)を
使用します。
コード中にsetColorの代わりに、setPaint()を使用しておけば、後にjava.awt.TexturePaint、java.awt.GradientPaintや独自に作成した
java.awt.Paint実装クラスに切り替えることが容易になります。

まぁ、これらのメソッドをGraphics2Dではなく、Graphicsに実装してくれれば、
理解も操作も楽で良いのにと思いますが。
takka
会議室デビュー日: 2004/08/24
投稿数: 7
投稿日時: 2006-11-12 17:58
一つだけ質問です。

イメージを描画したあとで、背景を描画すると、イメージが消えると思うのですが違うのでしょうか。
nekoyama
ベテラン
会議室デビュー日: 2005/03/12
投稿数: 71
投稿日時: 2006-11-12 19:38
引用:

takkaさんの書き込み (2006-11-12 17:58) より:
一つだけ質問です。

イメージを描画したあとで、背景を描画すると、イメージが消えると思うのですが違うのでしょうか。


間違っていたら、すみません。
私が、勝手に想定していたレベルとギャップがありました。

クリップの意味が分からないのであれば、これ以上説明しても仕方がないので、
クリップの意味を勉強してから、もう一度読み返してください。
sawat
大ベテラン
会議室デビュー日: 2006/08/02
投稿数: 112
投稿日時: 2006-11-13 13:38
やりたいのはこう言う事ですか?
コード:
import java.awt.*;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;

public class ImageTest extends JFrame {

   public static void main(String[] args) throws IOException {

      ImageTest f = new ImageTest("ImageTest");

      f.pack();
      f.setVisible(true);
   }

   public ImageTest(String title) throws IOException {
      super(title);

      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

      // 画像ファイルのURL
      URL resource = ImageTest.class.getClassLoader().getResource("hoge.gif");
      
      BufferedImage image      = ImageIO.read(resource);
      BufferedImage lightImage = createLightImage(image);
      Icon icon      = new ImageIcon(image);
      Icon lightIcon = new ImageIcon(lightImage);
      
      getContentPane().add(
            new JLabel("元の画像", icon, SwingConstants.CENTER),
            BorderLayout.NORTH);

      getContentPane().add(
            new JLabel("淡い画像", lightIcon, SwingConstants.CENTER),
            BorderLayout.SOUTH);
   }
   /** 淡い色のイメージを作成する。 */
   private BufferedImage createLightImage(BufferedImage image) {
      int h = image.getHeight();
      int w = image.getWidth();
      
      BufferedImage destImage = new BufferedImage(w, h,
            BufferedImage.TYPE_INT_ARGB);

      for(int y=0;y<h;y++) {
         for(int x=0;x<w;x++) {
            int rgb = image.getRGB(x, y);
            Color c = new Color(rgb, true);
            int a = c.getAlpha();
            int r = (c.getRed()   + 255) / 2;
            int g = (c.getGreen()   + 255) / 2;
            int b = (c.getBlue()   + 255) / 2;
            destImage.setRGB(x, y, new Color(r, g, b, a).getRGB());
         }
      }
      return destImage;
   }
}


透過部分のあるGIFだかPNGだかを読み込んで、
アルファ値をそのままにして、RGBを白っぽくしてます。
mio
ぬし
会議室デビュー日: 2005/08/25
投稿数: 734
お住まい・勤務地: 神奈川県
投稿日時: 2006-11-13 14:11
http://www.javaroad.jp/bbs/answer.jsp?q_id=20061111111749890

コードを掲載してくれている人もいますので、こちらにもレスをいただけませんか。
びしばし
大ベテラン
会議室デビュー日: 2002/03/13
投稿数: 181
投稿日時: 2006-11-13 15:38
「淡く」が曖昧ですが、白飛ばしっぽくすることですか ?

各ピクセル値をいじるなら、RGBじゃなくてHSVのS(彩度)をいじった方がいいかもしれませんね。

白との合成で、形を抽出するには、画像演算をします。
Javaでこういうことを高速に処理してくれるライブラリがあるといいのですが、ないならばゴリゴリと書くしかないかもしれません。

(1) 白一面画像(四角) AND 画像(四角じゃない) = 白画像(四角じゃない)
(2) (1) OR 画像 = 白っぽくなった画像 (四角じゃない)
(3) 背景 + (2) = 望む処理 ?
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2006-11-13 15:57
引用:

びしばしさんの書き込み (2006-11-13 15:38) より:
白との合成で、形を抽出するには、画像演算をします。
Javaでこういうことを高速に処理してくれるライブラリがあるといいのですが、ないならばゴリゴリと書くしかないかもしれません。



2D全盛時代にグラフィックやった人間なら割と常識っぽい処理ですが
あまりJavaで2Dごりごりやるって話は聞かないからアプローチが
間違っているのかなぁと思って静観していました。

グラフィックのアルゴリズムを学ぶなら
http://www.amazon.co.jp/gp/product/479800958X
あたりが入門書としては手ごろかなぁ。
C++なのでアルゴリズムの参考といったところですが。
takka
会議室デビュー日: 2004/08/24
投稿数: 7
投稿日時: 2006-11-15 01:04
みなさん、どうもありがとうございました。
無事に解決することができました。

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