C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[1]: フェードアウト(イン)をうまく表現できません


(過去ログ 80 を表示中)

[トピック内 12 記事 (1 - 12 表示)]  << 0 >>

■47369 / inTopicNo.1)  フェードアウト(イン)をうまく表現できません
  
□投稿者/ Lese (1回)-(2010/02/28(Sun) 15:36:08)

分類:[C#] 

初めまして。Leseと申します。初投稿になりますが、これからも宜しくお願いいたします。
プログラミング歴約一年ほどC言語をやっていただけです。
C#言語は始めてから1週間ほどです。C#を始める前に一応入門書を2冊読みました。

パソコンOS:Windows XP Home Edition SP3(32bit)
使用ソフト:Microsoft VisualStudio2008 Professional Edition
メモリー:3GB
CPU:Core i7 (Over Clockして3.08GHz)
※他に必要な情報があれば全てお答えします。


経緯についてですが、現在私は友人と本格的なゲームの作成をしています。
システムや、プログラミング、仕様、音関係は私で友人は絵を担当するという感じです。
製作したゲームはWindowsで起動させる為にWindowsフォームアプリケーションが作れるC#に決めました。(C++でもよかったのですが、C#を使うことにしました。)
数値や制御関係の処理はC言語をやってたこともあってスムーズにいきますが、画像関係だけがどうもうまくいきません;;
※経緯はこんな感じです。


問題点:画像をフェードアウトさせて描画してもlabelやピクチャボックスの背景がFormのbackgroundimageになってしまう。
プログラム:
        private void MainForm_MouseClick(object sender, MouseEventArgs e)
        {
                fadein(this.CreateGraphics(), Properties.Resources.sakura, 10, 10);    //フェードイン
        }


        /////////////////////////////////////////////////////////////////////////////////////////////////////////
        //フェードイン関数:戻り値無し
        //fadein(pictureBox.CreateGraphics(),Properties.Resources.イメージ名,フェード段階,フェード間隔,)
        //
        /////////////////////////////////////////////////////////////////////////////////////////////////////////

        private void fadein(Graphics obj, Image pic, float fadetime, int sleeptime)      
        {
            //PictureBox1のGraphicsオブジェクトを取得
            Graphics g = obj;
            //画像を読み込む
            Image img = pic;
            //フェードイン
            for (float i = 1; i <= fadetime; i++)
            {
                //半透明で画像を描画
                DrawFadedImage(g, img, i /fadetime );
                //一時停止
                System.Threading.Thread.Sleep(sleeptime);
            }
            //リソースを開放する
            //img.Dispose();
            //g.Dispose();
        }

        public void DrawFadedImage(Graphics g, Image img, float alpha)  //フェードインアウト処理2
        {
            //背景を用意する
            Bitmap back = new Bitmap(img.Width, img.Height);
            //backのGraphicsオブジェクトを取得
            Graphics bg = Graphics.FromImage(back);
            //白で塗りつぶす
            bg.Clear(Color.White);
            //ColorMatrixオブジェクトの作成
            System.Drawing.Imaging.ColorMatrix cm =
                new System.Drawing.Imaging.ColorMatrix();
            //ColorMatrixの行列の値を変更して、アルファ値がalphaに変更されるようにする
            cm.Matrix00 = 1;
            cm.Matrix11 = 1;
            cm.Matrix22 = 1;
            cm.Matrix33 = alpha;
            cm.Matrix44 = 1;
            //ImageAttributesオブジェクトの作成
            System.Drawing.Imaging.ImageAttributes ia =
                new System.Drawing.Imaging.ImageAttributes();
            //ColorMatrixを設定する
            ia.SetColorMatrix(cm);
            //ImageAttributesを使用して背景に描画
            bg.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height),
                0, 0, img.Width, img.Height, GraphicsUnit.Pixel, ia);
            //合成された画像を表示
            g.DrawImage(back, 0, 0);
            //リソースを開放する
            bg.Dispose();
            back.Dispose();
        }

プログラムの説明ですが、bmpファイルのRGBA値のA値を段々あげていくことによってフェード効果を得ているのですが、
これだと、Formのbackgroundimageは一定のまま、その上の層にフェード効果を得ていることになる為、フェード中にlabelやpictureboxの背景はformのbackgroundimageとなってしまいます。
そして、このプログラムによって描かれた画像はFormをパソコンの画面外に移動させて画面内に戻すと消えてしまうといった問題も出てきます。


この問題点の解決策をどうかご教授お願いいたします。


インターネットで検索し、書籍も読みましたが、画像処理等について書かれたページが少なくここに投稿することを決めました。
画像処理はゲームを作る上で最も大事なとこだと思っていますので是非マスターしたいです。

どうか宜しくお願いします(m´・ω・`)m

引用返信 編集キー/
■47417 / inTopicNo.2)  Re[1]: フェードアウト(イン)をうまく表現できません
□投稿者/ 自作 (19回)-(2010/03/02(Tue) 09:24:40)
No47369 (Lese さん) に返信
> インターネットで検索し、書籍も読みましたが、画像処理等について書かれたページが少なくここに投稿することを決めました。
「C# フェードアウト」で検索すればいいだけでは?
引用返信 編集キー/
■47420 / inTopicNo.3)  Re[1]: フェードアウト(イン)をうまく表現できません
□投稿者/ はつね (1205回)-(2010/03/02(Tue) 10:50:11)
No47369 (Lese さん) に返信
> 経緯についてですが、現在私は友人と本格的なゲームの作成をしています。
> システムや、プログラミング、仕様、音関係は私で友人は絵を担当するという感じです。
> 製作したゲームはWindowsで起動させる為にWindowsフォームアプリケーションが作れるC#に決めました。(C++でもよかったのですが、C#を使うことにしました。)

C#でゲームでWinフォームアプリならXNAとか使ってみたら?

引用返信 編集キー/
■47431 / inTopicNo.4)  Re[1]: フェードアウト(イン)をうまく表現できません
□投稿者/ 魔界の仮面弁士 (1515回)-(2010/03/02(Tue) 14:25:32)
No47369 (Lese さん) に返信
> private void MainForm_MouseClick(object sender, MouseEventArgs e)
> {
>         fadein(this.CreateGraphics(), Properties.Resources.sakura, 10, 10);    //フェードイン
> }
コントロールの CreateGraphics メソッドを呼び出すのではなく、描画関係のコードは
すべて Paint イベントに記述し、引数の e.Graphics を利用するようにしてみてください。

そうすれば、
> このプログラムによって描かれた画像はFormを
> パソコンの画面外に移動させて画面内に戻すと消えてしまう
という問題も解決するかと思います。


フェードイン/アウトのように連続して再描画を行う必要がある場合には、
PictureBox に対して描画要求を行い、Paint イベントが発生するように呼びかけます。

再描画が必要である事を通知させるには、以下のメソッドを利用します。
 Invalidate メソッド … 再描画が必要である事を通知する。
 Update メソッド   … 再描画を行う。ただし再描画が不要な時は何もしない。
 Refresh メソッド   … 強制再描画。Invalidate と Update を連続して呼ぶのと同義。


> System.Threading.Thread.Sleep(sleeptime);
コントロールを操作しているスレッドからは、Sleep メソッドを呼び出さないでください。
代わりに Timer を利用して、一定時間ごとに Invalidate (または Refresh) を呼び出すようにします。
ちらつきを抑えるために、DoubleBuffered プロパティは true にしておく事をおすすめします。


> フェード中にlabelやpictureboxの背景はformのbackgroundimageとなってしまいます。
負荷が問題にならないなら、BackgroundImage そのものを差し替えるという手もあります。
フォーム全体をフェードアウトさせるでも良ければ、Opacity プロパティを利用するのが簡単かも。

引用返信 編集キー/
■47453 / inTopicNo.5)  Re[2]: フェードアウト(イン)をうまく表現できません
□投稿者/ Lese (2回)-(2010/03/02(Tue) 22:29:56)
皆さん参考になるレスをしてくださってありがとうございます。

>>自作様

「C# フェードアウト」で検索して自分で作成したプログラムが最初に書いたプログラムになっております。
そのプログラムで問題が生じ、自分一人では解決できなかったのでここに投稿を決めました。
しかし、私の検索能力が低いということも感じています。もっと精進していきたいと思います。ありがとうございました。


>>はつね様
「C# XNA」で検索してみました。
まだ少ししか理解できていないのですが、画像関係の扱いは凄く扱いやすそうな印象を受けました。
今回のゲーム作成に使用するかどうかはまだ検討中ですが、XNAというツールは非常に興味深いです。貴重な情報を提供してくださってありがとうございました。


>>魔界の仮面弁士様
具体的で非常に分かりやすいレスを書いてくださってありがとうございます。
プログラムはまだ製作中ですが、解決に近づけそうな気がします。
今まで打つ手なしの状態でしたのでここから一歩を踏み出せそうです。
本当に助かりました。どうもありがとうございます。

解決済み
引用返信 編集キー/
■47457 / inTopicNo.6)  Re[3]: フェードアウト(イン)をうまく表現できません
□投稿者/ 自作 (21回)-(2010/03/03(Wed) 09:13:40)
No47453 (Lese さん) に返信
>「C# フェードアウト」で検索して自分で作成したプログラムが最初に書いたプログラムになっております。
しかしながら、.Net でフェードイン・アウトする場合、まずは Opacity プロパティを使う手法が
検索されると思います。google では、以下が Top に検索されます。
[C#プログラミングTips フェードイン/アウトするウィンドウを作るには]
http://www.atmarkit.co.jp/fdotnet/csharptips/004fade/004fade.html
完成されたサンプルコードが公開されています。

> プログラムの説明ですが、bmpファイルのRGBA値のA値を段々あげていくことによってフェード効果を得ているのですが
こうはならない訳です。
Opacity プロパティでは都合が悪かったとかいった経緯は書かれていませんので、調べないで自分の頭で
考えた手法で躓いているように見えます。
解決済み
引用返信 編集キー/
■47475 / inTopicNo.7)  Re[4]: フェードアウト(イン)をうまく表現できません
□投稿者/ Lese (3回)-(2010/03/03(Wed) 19:14:35)
>>自作様
Opacityプロパティによって透明化できるのはForm全体ですよね?
私はForm全体を透明化したいのではなくForm上のPictureBoxとかDrawImageによってできた”画像”をフェードアウトさせたいわけです。
よってOpacityプロパティ変更では私の目的は達せられません。

>Opacity プロパティでは都合が悪かったとかいった経緯は書かれていませんので、調べないで自分の頭で
>考えた手法で躓いているように見えます。
いいえ、ネット上からサンプルコードを拾ってきています。
http://dobon.net/vb/dotnet/graphics/hadeinimage.html
そのコードから自分の使いやすいように少し手を加えただけです。プログラムを比較してもらえれば一目瞭然かと思います。


もう一つ。
Opacityプロパティでは都合が悪かったとかいった経緯を書かなければ、調べていないということにはならないと思います。
私は一番最初に
>インターネットで検索し、書籍も読みましたが、画像処理等について書かれたページが少なくここに投稿することを決めました。
と、書きました。
貴方は私が嘘をついているように見えたのでしょうか?
勝手な憶測だけで適当なことを書かないでほしいです。


質問者でありながら非常に無礼極まりない書き込みであることは承知していますが、これが私の本音です。
ごめんなさい。
引用返信 編集キー/
■47482 / inTopicNo.8)  Re[1]: フェードアウト(イン)をうまく表現できません
□投稿者/ 魔界の仮面弁士 (1527回)-(2010/03/03(Wed) 20:49:59)
No47369 (Lese さん) に返信
> フェード中にlabelやpictureboxの背景はformのbackgroundimageとなってしまいます。
Form 上に Label (BackColor = Transparent) を配置した場合、
親コントロールのである Form の背景が利用されます。

PictureBox の背景を使いたいのであれば、
 this.Controls.Add(label1);
ではなく、
 this.pictureBox1.Controls.Add(label1);
のように、PictureBox に載せてみてください。
http://dobon.net/vb/dotnet/control/labelonpicturebox.html


とりあえず下記では、PictureBox を使わずに Form 上に直接描画しています。
フェード用に Timer を用意しておいてください。


public partial class Form1 : Form
{
    float alpha = 1.0f;
    float diff = -0.05f;

    Image baseImage;
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        //HACK => http://dobon.net/vb/dotnet/graphics/drawpicture2.html
        baseImage = Image.FromFile(@"C:\WINDOWS\大草原の風.bmp");
        DoubleBuffered = true;
        timer1.Interval = 120;
    }

    private void Form1_Shown(object sender, EventArgs e)
    {
        timer1.Start();
    }
    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        timer1.Stop();
    }

    private void Form1_FormClosed(object sender, FormClosedEventArgs e)
    {
        baseImage.Dispose();
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        alpha += diff;
        if (alpha <= 0f)
        {
            alpha = 0f; diff = -diff;
        }
        else if (alpha >= 1.0f)
        {
            alpha = 1.0f;
            diff = -diff;
        }
        this.Invalidate();
    }

    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        using (Image img = CreateFadedImage(baseImage, alpha))
        {
            e.Graphics.DrawImage(img, 0, 0);
        }
    }

    public Image CreateFadedImage(Image img, float alpha)
    {
        ColorMatrix cm = new ColorMatrix();
        cm.Matrix00 = 1.0f;
        cm.Matrix11 = 1.0f;
        cm.Matrix22 = 1.0f;
        cm.Matrix33 = alpha;
        cm.Matrix44 = 1.0f;

        Bitmap bmp = new Bitmap(img.Width, img.Height);

        using (Graphics bg = Graphics.FromImage(bmp))
        using (ImageAttributes ia = new ImageAttributes())
        {
            bg.Clear(Color.White);
            ia.SetColorMatrix(cm);
            bg.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height),
                0, 0, img.Width, img.Height, GraphicsUnit.Pixel, ia);
        }
        return bmp;
    }
}

引用返信 編集キー/
■47489 / inTopicNo.9)  Re[5]: フェードアウト(イン)をうまく表現できません
□投稿者/ 自作 (23回)-(2010/03/04(Thu) 10:28:23)
No47475 (Lese さん) に返信
> よってOpacityプロパティ変更では私の目的は達せられません。
まずこの結論は誰が出したのですか?Opacity プロパティの操作で透明化できる「Form 全体」に
Form上のコントロールは当然含まれていますし、PictureBox も透明化できます。
”画像”についても、少なくともすぐ実験できる Image プロパティに設定したものは透明化できますよ。
確認済みです。自分で描画した線も透明化されます。これも確認済みです。
つまり、貴方の描画方法に問題があるのではないんですか?

> 貴方は私が嘘をついているように見えたのでしょうか?
> 勝手な憶測だけで適当なことを書かないでほしいです。
Opacity プロパティについて調べていないように、実際に見えますよね?
ですから、■47475 の説明が最初の質問の時点で必要です。
それが丸々抜けていると言っています。

> Opacityプロパティでは都合が悪かったとかいった経緯を書かなければ、調べていないということに
> はならないと思います。
こちらには調べた内容は伝わりません。実際に伝わっていません。
今回は特に、貴方の調べた内容が不十分と思われますので、書く必要があった事が明白ですよね。
引用返信 編集キー/
■47495 / inTopicNo.10)  Re[6]: フェードアウト(イン)をうまく表現できません
□投稿者/ 魔界の仮面弁士 (1528回)-(2010/03/04(Thu) 12:34:33)
No47489 (自作 さん) に返信
>>よってOpacityプロパティ変更では私の目的は達せられません。
> まずこの結論は誰が出したのですか?Opacity プロパティの操作で透明化できる「Form 全体」に
> Form上のコントロールは当然含まれていますし、PictureBox も透明化できます。

Form 上のコントロールを透明化したいという話は無かったと思いますが…。
コントロールの背景画像をフェードアウトさせたいという話ではありませんでしたっけ?
引用返信 編集キー/
■47496 / inTopicNo.11)  Re[7]: フェードアウト(イン)をうまく表現できません
□投稿者/ 自作 (24回)-(2010/03/04(Thu) 12:52:32)
2010/03/04(Thu) 13:30:59 編集(投稿者)

No47495 (魔界の仮面弁士 さん) に返信
> Form 上のコントロールを透明化したいという話は無かったと思いますが…。
> コントロールの背景画像をフェードアウトさせたいという話ではありませんでしたっけ?
おおぅ。コントロールの背景画像”だけ”ですか?もしかして。

質問タイトルとコードを流し読みして、なんでこんな面倒を。。。としか思いませんでした。
無理やりOpacity使うなら、
フォーム内にフォームを表示する
http://dobon.net/vb/dotnet/form/formwithinform.html
などと組み合わせてみるとか、新しいアイデアと検証が必要で
使えないと判断した方がいいのか。
それで
>> フェード中にlabelやpictureboxの背景はformのbackgroundimageとなってしまいます。
>負荷が問題にならないなら、BackgroundImage そのものを差し替えるという手もあります。
>フォーム全体をフェードアウトさせるでも良ければ、Opacity プロパティを利用するのが簡単かも。
ですか。なるほど。
失礼しました。ごめんなさい。
引用返信 編集キー/
■47519 / inTopicNo.12)  Re[8]: フェードアウト(イン)をうまく表現できません
□投稿者/ 魔界の仮面弁士 (1529回)-(2010/03/04(Thu) 17:17:48)
No47496 (自作 さん) に返信
> 無理やりOpacity使うなら、
> フォーム内にフォームを表示する
> http://dobon.net/vb/dotnet/form/formwithinform.html
> などと組み合わせてみるとか、

あれ? 重ねるのはともかく、載せてしまっては駄目なのでは?

レイヤード ウィンドウが使えるのは、トップレベル ウィンドウだけですので、
子ウィンドウにしてしまったら、内側フォームの Opacity は無効になるような…。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -