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

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

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

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

Swing

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

Q&A

解決済

2回答

2690閲覧

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

otftrough

総合スコア476

Java

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

Swing

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

0グッド

0クリップ

投稿2016/03/17 06:37

下記のプログラムで、画像を徐々に薄くして非表示にできました。
これの逆で、徐々に濃くしながら表示させようとしたんですが、何故か、少し表示されてからまた消えてしまいました。ちゃんとフェードインするにはどうすれば良いでしょうか?
また、画像の不透明度をもっと効率よく変更することは可能ですか?
私のPC(win10 32bit 1.33GHz 2.00GB)だと少し動作が遅いです。

実際にダウンロードして確認していただけます。

徐々に濃くしていく方のプログラムは、
pixel[i] = pixel[i] & (0x00FFFFFF + a * 0x1000000);

pixel[i] = pixel[i] & (0x00FFFFFF + (255 - a) * 0x1000000);
に変更しただけです。

java

1import java.awt.*; 2import java.awt.image.*; 3import java.awt.event.*; 4import javax.swing.*; 5import javax.swing.Timer; 6import java.io.*; 7 8class Test extends JFrame implements ActionListener{ 9 10 public static void main(String[] args){ 11 12 Test f = new Test(); 13 f.setTitle("Test"); 14 f.setBounds(100,100,500,250); 15 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 16 f.setVisible(true); 17 } 18 19 JLabel label; 20 Timer timer; 21 ImageIcon icon; 22 Image img; 23 int width; 24 int height; 25 int[] pixel; 26 int a; 27 boolean click = true; 28 29 Test(){ 30 31 JPanel base = new JPanel(); 32 base.setLayout(new BoxLayout(base, BoxLayout.X_AXIS)); 33 add(base); 34 35 icon = new ImageIcon("img.png"); 36 label = new JLabel(icon); 37 base.add(label); 38 39 JButton btn = new JButton("start"); 40 btn.addActionListener(this); 41 base.add(btn); 42 } 43 44 public void actionPerformed(ActionEvent e){ 45 46 if(click){ 47 48 click = false; 49 timer = new Timer(50, new FadeOut()); 50 a = 255; 51 img = icon.getImage(); 52 width = icon.getIconWidth(); 53 height = icon.getIconHeight(); 54 pixel = new int[width * height]; 55 PixelGrabber pg = new PixelGrabber(img, 0, 0, width, height, pixel, 0, width); 56 try{ 57 58 pg.grabPixels(); 59 } catch(InterruptedException ex){ 60 61 ex.printStackTrace(); 62 } 63 64 timer.start(); 65 } 66 } 67 68 private class FadeOut implements ActionListener{ 69 70 public void actionPerformed(ActionEvent e){ 71 72 a -= 15; 73 System.out.println("Alpha:" + a); 74 int color = new Color(255,255,255,0).getRGB(); 75 for(int i = 0; i < pixel.length; i ++) if(pixel[i] != color) pixel[i] = pixel[i] & (0x00FFFFFF + a * 0x1000000); 76 img = Toolkit.getDefaultToolkit().createImage(new MemoryImageSource(width, height, pixel, 0, width)); 77 label.setIcon(new ImageIcon(img)); 78 if(a == 0){ 79 80 timer.stop(); 81 System.out.println("stop"); 82 click = true; 83 } 84 } 85 } 86}

参考にしたサイト:イメージの特定色を透明にしたい(アイコンなど)

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

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

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

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

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

guest

回答2

0

ベストアンサー

上のコメントで伝わらなかったのなら何と書いていいか困惑してしまいますが…
勉強していない箇所が判明して必要性を感じたのなら是非そこの勉強をしてください。
私も説明が得意な訳ではないので余計混乱させるかもしれませんが、窓が沢山並んでいる状態で
11101110
と1が空いてる窓、0が閉まってる窓という並びの場合これらの窓の向こう側にある景色が
10111111
だった時に窓越しに見える世界は
10101110
という景色です。閉じた窓の向こうが見えないのでそこがマスクされた状態です。
(空いてる窓の所は向こうの景色がそのまま入るので向こうの景色に連動し、閉じてる窓の所は必ず0という結果)
今回 a-=15 としているのでマスクするために使う窓が
11111111 (FF,255)

11110000 (F0,240)

11100001 (E1,225)

11010010 (D2,210)

(以下略)
と変化しています。
窓が開いたり閉じたりする場所を考えて、本当にそんな順番でマスクする事を望んでいたのでしょうか?
1度窓を閉じて0にしてしまった世界はそれ以降何度窓を開閉繰り返しても0のまま変わりません。
(もちろん元の景色が窓の開閉結果によって上書きされていないのなら別ですが)
そしてこれが一番重要で根本的な事なんですが「&」でマスクするだけでは今回やりたかった事を実現できるはずがありません。
0に向かって収束させて行く時は最終目標が0なので途中経過が違っても最後の目的だけは達成できました。
しかしFFに向かって収束させるならマスクしただけではダメですよね?
マスクしてるだけでは消える事はあっても増える事は無いのですから。
やるのなら
1.0x00FFFFFF で一旦αだけを消す(α以外だけを抽出する)
2.α(00~FF)を24bit左にシフトして0x00000000~0xFF000000の状態にして1の結果と合成する
3.2で合成した結果を採用する
という手順が必要では無いでしょうか?
あなたがしているのは
1.0x(α値00-FF)FFFFFFでα値部分を消す
という事だけです
…という感じですがこれで伝わったでしょうか…

投稿2016/03/18 01:25

HiroshiWatanabe

総合スコア2160

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

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

HiroshiWatanabe

2016/03/18 01:27

あ…入力場所間違えました…ごめんなさい…上の回答のコメントにコメントするつもりが…
otftrough

2016/03/19 15:01

ありがとうございます、伝わりました。
guest

0

今のpixel[i]の値を加工してpixel[i]に戻していますね
計算して求めているアルファのマスク値はFF->F0->E1->D2->C3...と変化しているので
1.FFでマスクしてFFだった値がFFに変化し
2.F0でマスクしてFFだった値がF0に変化し
3.E1でマスクしてF0だった値がE0に変化し
4.D2でマスクしてE0だった値がC0に変化し
(以下略)
としている事になります。
画像を消していく(アルファ値を徐々に0にして行く)場合は、意図しない減り方だったとしても
結果的にアルファが0になってさえくれれば消えるので結果だけは目的を達成できている状態です。
逆に表示させたいからとこのマスクの計算式を変更しただけでは、例えば
1.00でマスクしてFFだった値が00に変化し
2.0Fでマスクして00だった値が00に変化し
3.1Eでマスクして00だった値が00に変化し
(以下略)
と最初のマスクが適用されるまでは初期値の状態で表示はされているけどマスクが適用されてしまうと
それ以降はずっとアルファが0の状態で見えない表示を続けている、という状態なんでしょうね。

投稿2016/03/17 07:02

編集2016/03/17 07:16
HiroshiWatanabe

総合スコア2160

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

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

otftrough

2016/03/17 08:31

ビット演算子というのを勉強していなかったので、&を%と勘違いしていたようです。 0x00FFFFFFを好きな値に変えてpixel[i]&それ で良いというわけではないんですか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問