質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Swing

SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。

Q&A

解決済

1回答

4927閲覧

swingでJLabelに表示している画像の透明度を変更する方法がわかりません。

otftrough

総合スコア476

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Swing

SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。

0グッド

1クリップ

投稿2016/03/16 03:57

編集2016/03/17 02:22

ググっても、出てきませんでした。
とりあえず、こんな感じのアニメーションを作ろうと思っています。

java

1//import javax.swing.Timer; 2//Timer timer; 3//JPanel panel; 4//JLabel label; 5 6label = new JLabel(new ImageIcon("hoge.png")); 7panel.add(label); 8 9int h = 255; 10Icon icon = label.getIcon(); 11timer = new Timer(50, new hoge()); 12timer.start();

java

1private class hoge implements ActionListener{ 2 3 public void actionPerformed(ActionEvent e){ 4 5 h -= 15; 6 //iconの不透明度 = h; 7 label.setIcon(icon); 8 if(h == 0) timer.stop(); 9 } 10}

追記:
自分のPCの環境は、Win10 64bit, Win10 32bit, Win8.1 64bitの3つで、
Javaは1.8.0です。
今作っているのはゲームで、ユーザーのPCでも1.8.0で動けばいいと思っています。
今回透過させたいと思っているのは、JLabelに表示させたキャラクターのpng画像で、表示させる時と消すときにふわっと出てきたり消えたりするアニメーション(不透明→半透明→透明 または逆)を作ろうと思っていて、できればJLabelのまま画像を半透明にしたいと思っていますが、画像のサイズと位置がそのままで半透明にできるなら、JLabelであることにこだわりません。

半透明や透明にする方法を調べても、指定された色を透明色に変更する例や、50x50の水色の矩形の画像を用意などが出てきて、これをアニメーションで使うのはあまり効率が良くないのではと思い、ここで質問しました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

lib

2016/03/16 15:52 編集

ご使用のOSの環境とjavaのバージョンと作成環境 可能な限りの情報提供をお願いします。また、調べたこと、確認したことも書いてください。あとこれは質問ですが、JLabelの画像を透明にする必要性があるのかどうか。たとえばPanelやJFrameにのっけたものでもよいものなのか。もしくは描画方法がswingじゃなくてもよいものなのか。
guest

回答1

0

ベストアンサー

下記の質問に関連するのですが。

たぶんアルゴリズムの問題。画像の不透明度を上げながらフェードイン(?)したいんですが。(30013)|teratail
https://teratail.com/questions/30013

MemoryImageSourceって、今回のケースだとすべてのピクセルに透明度を設定するので効率が悪いような気がします。

「50x50の水色の矩形の画像を用意」で回答されているもの近い方法の、AlphaCompositeで透明度を変える処理の例を示します。

lang

1import java.awt.*; 2import java.awt.event.*; 3import java.util.concurrent.Executors; 4import javax.swing.*; 5 6final class MyPanel extends JPanel { 7 8 JFrame frame; 9 Image img; 10 volatile float alpha; 11 int imageWidth = 145; // TODO 画像に合わせて変える 12 int imageHeight = 157; // TODO 画像に合わせて変える 13 14 MyPanel(JFrame f) { 15 this.frame = f; 16 this.img = new ImageIcon("img.png").getImage(); 17 this.alpha = 0.0f; 18 } 19 20 @Override 21 protected void paintComponent(Graphics g) { 22 Graphics2D g2 = (Graphics2D)g; 23 System.out.println("alpha=" + alpha); 24 g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha)); 25 g2.drawImage(img, 0, 0, imageWidth, imageHeight, this); 26 } 27 28 void fadeIn() { 29 Executors.newSingleThreadExecutor().execute(new Runnable() { 30 public void run() { 31 while (alpha < 1.0f) { 32 float f = alpha + 0.03f; 33 if (f > 1.0f) { 34 alpha = 1.0f; 35 break; 36 } 37 alpha = f; 38 frame.repaint(); 39 sleep(50L); 40 } 41 } 42 }); 43 } 44 45 void fadeOut() { 46 Executors.newSingleThreadExecutor().execute(new Runnable() { 47 public void run() { 48 while (alpha >= 0.0f) { 49 float f = alpha - 0.03f; 50 if (f < 0.0f) { 51 alpha = 0.0f; 52 break; 53 } 54 alpha = f; 55 frame.repaint(); 56 sleep(50L); 57 } 58 } 59 }); 60 } 61 62 static void sleep(long millis) { 63 try { 64 Thread.sleep(millis); 65 } catch (InterruptedException e) { 66 throw new RuntimeException(e); 67 } 68 } 69 70} 71 72public final class App { 73 74 public static void main(String[] args) { 75 EventQueue.invokeLater(new Runnable() { 76 public void run() { 77 JFrame f = new JFrame("test"); 78 f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 79 f.setSize(600, 400); 80 f.setLocationRelativeTo(null); 81 JPanel p = new JPanel(); 82 MyPanel canvas = new MyPanel(f); 83 JButton fadeOutButton = new JButton("fade out"); 84 fadeOutButton.addActionListener(new ActionListener() { 85 @Override 86 public void actionPerformed(ActionEvent e) { 87 canvas.fadeOut(); 88 } 89 }); 90 JButton fadeInButton = new JButton("fade in"); 91 fadeInButton.addActionListener(new ActionListener() { 92 @Override 93 public void actionPerformed(ActionEvent e) { 94 canvas.fadeIn(); 95 } 96 }); 97 p.add(fadeInButton); 98 p.add(fadeOutButton); 99 f.add(canvas, BorderLayout.CENTER); 100 f.add(p, BorderLayout.NORTH); 101 f.setVisible(true); 102 } 103 }); 104 } 105 106}

排他制御する箇所は省略しているため、どちらかの処理が動いているときにもう片方の処理を動かすとおかしなことになりますのでご注意ください。

それと、ここはあまり自信が無いのですが、透明化に限らず、Java2Dの機能で画像の加工処理・フィルター処理などを使う場合、描画するパネルだけをrepaintするとおかしな挙動になることがあります。
そのため、今回の例ではフレームごと再描画させるようにしています。

参考リンク:

Crossfadeで画像の切り替え - Java Swing Tips
http://ateraimemo.com/Swing/Crossfade.html

投稿2016/03/18 03:43

argius

総合スコア9388

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otftrough

2016/03/19 15:36

おっ、これはいける・・・
otftrough

2016/03/22 11:15

Graphics g; は、どこからもらってきてるんですか? arguisさんのコードとほかのサイトを参考に自分でも作ってみましたが、 java.lang.UnsupportedOperationException: getGraphics() not valid for images created with createImage(producer)というエラーが出ました。createImage()で作ったImageしかgetGraphics()できないということでしょうか?
argius

2016/03/22 11:28

このコードの方法に限っていうと、 Graphics gは、paintComponentメソッドが呼ばれた際に渡されるもので、 任意の場所で使用できるものではありません。 他の方法でとなると、私も分からないですね。
argius

2016/03/22 12:54

複数のスレッド間で値を共有する場合、volatileキーワードをつけないと上手く動作しないことがあります。 int aにはvolatileつけたほうが良いかも知れません。 Graphics2D g2は一過性のものなので、フィールドに持つのはやめたほうが良いです。 使ってないみたいなので大丈夫だとは思いますけど。 とりあえず重要なのはそのくらいですかね。
otftrough

2016/03/22 14:03

ありがとうございます、volatile調べて勉強しておきます。 そうですね、g2の場所は、移動を忘れていました。よくわからないまま弄ってた時の名残です。 今はこうなっています。 private class FLabel extends JLabel{ private Image img; volatile int alpha; //0~255 public FLabel(){}; public FLabel(String str){ this.setText(str);} public FLabel(ImageIcon icon){ this.setIcon(icon); if(icon != null) img = icon.getImage(); else img = null; } public void setIconAndImage(ImageIcon icon){ setIcon(icon); if(icon != null) img = icon.getImage(); else img = null; } public void paintComponent(Graphics g){ Graphics2D g2 = (Graphics2D)g; g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float)alpha / (float)255)); if(img != null) g2.drawImage(img, 0, 0, getIcon().getIconWidth(), getIcon().getIconHeight(), this); } }
otftrough

2016/03/22 14:08

あ、volatileそういう意味じゃなかったか
argius

2016/03/22 14:08

だいぶスッキリしましたね。 良いと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問