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

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

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

Re[4]: ピクチャボックスでデスクトップにキャラクター


(過去ログ 109 を表示中)

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

■64753 / inTopicNo.1)  ピクチャボックスでデスクトップにキャラクターを表示
  
□投稿者/ ごりま (1回)-(2013/01/04(Fri) 20:46:49)

分類:[C#] 

2013/01/05(Sat) 01:38:50 編集(投稿者)

C#でプログラミングをしているのですが、ピクチャボックスで透明処理してあるPNGファイルを読み込ませてフォームも

this.FormBorderStyle = FormBorderStyle.None;
this.TransparencyKey = BackColor;
に設定してキャラクター画像のみ表示させたいのですが、この方法だとキャラクターの周りに線が出てしまいます
画像をご覧ください

線が出なく、きれいな画像を表示する方法を教えてください


http://gorima.no-ip.org/chie.jpg


引用返信 編集キー/
■64754 / inTopicNo.2)  Re[1]: ピクチャボックスでデスクトップにキャラクター
□投稿者/ Azulean (75回)-(2013/01/04(Fri) 23:45:00)
2013/01/04(Fri) 23:47:16 編集(投稿者)

No64753 (ごりま さん) に返信
> 線が出なく、きれいな画像を表示する方法を教えてください

元となる PNG の時点でキャラクターの周囲に、背景色とキャラクターの色との中間色が出てしまっていませんか?
減色処理やサイズ縮小などの処理を経ると、周囲の色と混ぜてしまうのできれいに透過できないことはよくあります。

仮に元となる PNG がきれいだったとしても、透過表示するまでの過程で縮小などをしていれば、その辺も怪しいです。

// それだけだと右側の右下に伸びる 2 本の髪の毛の変色が説明できないので、具体的に他の処理も知りたいところです。
// あとは実際に背景色としている色も。
引用返信 編集キー/
■64755 / inTopicNo.3)  Re[2]: ピクチャボックスでデスクトップにキャラクター
□投稿者/ Hongliang (28回)-(2013/01/05(Sat) 00:14:51)
背景(壁紙や他のウィンドウ)とのアルファブレンドが必要なら、多分.NETの標準ライブラリだけでは解決できません。
WS_EX_LAYEREDおよびUpdateLayerdWindow関数を使って自力で描画する必要があるでしょう。
引用返信 編集キー/
■64756 / inTopicNo.4)  Re[2]: ピクチャボックスでデスクトップにキャラクター
□投稿者/ ごりま (2回)-(2013/01/05(Sat) 01:39:11)
No64754 (Azulean さん) に返信
> 2013/01/04(Fri) 23:47:16 編集(投稿者)
>
> ■No64753 (ごりま さん) に返信
>>線が出なく、きれいな画像を表示する方法を教えてください
>
> 元となる PNG の時点でキャラクターの周囲に、背景色とキャラクターの色との中間色が出てしまっていませんか?
> 減色処理やサイズ縮小などの処理を経ると、周囲の色と混ぜてしまうのできれいに透過できないことはよくあります。
>
> 仮に元となる PNG がきれいだったとしても、透過表示するまでの過程で縮小などをしていれば、その辺も怪しいです。
>
> // それだけだと右側の右下に伸びる 2 本の髪の毛の変色が説明できないので、具体的に他の処理も知りたいところです。
> // あとは実際に背景色としている色も。



早速のご返答ありがとうございます
作成の流れとしては
1.C#2010にて新規フォームを作成
2.ピクチャボックスをフォームに貼り付けのち親コンテナにドッキング サイズはStretchImage
3.画像をリソースに取り込み、イメージを選択
4.private void Form1_Load(object sender, EventArgs e)に
   this.FormBorderStyle = FormBorderStyle.None;
   this.TransparencyKey = BackColor;
を貼り付けという作業です
実際のPNG画像を添付します
http://gorima.no-ip.org/879.png
※約30MB
実際のプロジェクトファイルも添付いたします
http://gorima.no-ip.org/test.zip
※約23MB

また、テスト用として円の図形(αPNG)を表示させても周りに線が出てしまいます。
この線はバックカラーの消しきれていないものと推測します。バックカラーを変えるとこの線の色も変わるからです
例としてバックカラーを変えたものを画像添付いたします。ご確認ください
http://gorima.no-ip.org/3.PNG
http://gorima.no-ip.org/4.PNG
http://gorima.no-ip.org/1.PNG
http://gorima.no-ip.org/2.PNG

引用返信 編集キー/
■64757 / inTopicNo.5)  Re[3]: ピクチャボックスでデスクトップにキャラクター
□投稿者/ ごりま (3回)-(2013/01/05(Sat) 01:41:09)
No64755 (Hongliang さん) に返信
> 背景(壁紙や他のウィンドウ)とのアルファブレンドが必要なら、多分.NETの標準ライブラリだけでは解決できません。
> WS_EX_LAYEREDおよびUpdateLayerdWindow関数を使って自力で描画する必要があるでしょう。


アドバイスありがとうございます
私がC#でプログラミングを始めたのが数日までで、まだわからないことが多いですので、おっしゃられた
> WS_EX_LAYEREDおよびUpdateLayerdWindow関数を使って自力で描画する必要があるでしょう。
の意味および使い方がまったくわかりません。
上記のものがどういうものなのかをご伝授いただけませんでしょうか?
引用返信 編集キー/
■64758 / inTopicNo.6)  Re[4]: ピクチャボックスでデスクトップにキャラクター
□投稿者/ shu (136回)-(2013/01/05(Sat) 13:18:54)
No64757 (ごりま さん) に返信
> ■No64755 (Hongliang さん) に返信
>>背景(壁紙や他のウィンドウ)とのアルファブレンドが必要なら、多分.NETの標準ライブラリだけでは解決できません。
>>WS_EX_LAYEREDおよびUpdateLayerdWindow関数を使って自力で描画する必要があるでしょう。
>
>
> アドバイスありがとうございます
> 私がC#でプログラミングを始めたのが数日までで、まだわからないことが多いですので、おっしゃられた
>>WS_EX_LAYEREDおよびUpdateLayerdWindow関数を使って自力で描画する必要があるでしょう。
> の意味および使い方がまったくわかりません。
> 上記のものがどういうものなのかをご伝授いただけませんでしょうか?
C#の経験が浅いのかプログラミング経験自体が浅いのかにもよると思いますが、プログラミング経験が浅いとすると
WindowsAPIの使用は結構ハードルが高くなると思います。というかもっと基本的なものを作ったらどうかと思う。

一応
http://amonution.sblo.jp/article/44207805.html
にこれらを使ったものが出ているので参考にしてみてはどうでしょう。
これはGoogle検索で適当に見つけたものです。キーワードが出てきたらインターネット上で検索してみるのも
必要だと思います。
引用返信 編集キー/
■64759 / inTopicNo.7)  Re[5]: ピクチャボックスでデスクトップにキャラクター
□投稿者/ ごりま (4回)-(2013/01/05(Sat) 18:17:46)
2013/01/05(Sat) 18:22:39 編集(投稿者)

No64758 (shu さん) に返信
> ■No64757 (ごりま さん) に返信
>>■No64755 (Hongliang さん) に返信
> >>背景(壁紙や他のウィンドウ)とのアルファブレンドが必要なら、多分.NETの標準ライブラリだけでは解決できません。
> >>WS_EX_LAYEREDおよびUpdateLayerdWindow関数を使って自力で描画する必要があるでしょう。
>>
>>
>>アドバイスありがとうございます
>>私がC#でプログラミングを始めたのが数日までで、まだわからないことが多いですので、おっしゃられた
> >>WS_EX_LAYEREDおよびUpdateLayerdWindow関数を使って自力で描画する必要があるでしょう。
>>の意味および使い方がまったくわかりません。
>>上記のものがどういうものなのかをご伝授いただけませんでしょうか?
> C#の経験が浅いのかプログラミング経験自体が浅いのかにもよると思いますが、プログラミング経験が浅いとすると
> WindowsAPIの使用は結構ハードルが高くなると思います。というかもっと基本的なものを作ったらどうかと思う。
>
> 一応
> http://amonution.sblo.jp/article/44207805.html
> にこれらを使ったものが出ているので参考にしてみてはどうでしょう。
> これはGoogle検索で適当に見つけたものです。キーワードが出てきたらインターネット上で検索してみるのも
> 必要だと思います。


再度アドバイスありがとうございます
> WindowsAPIの使用は結構ハードルが高くなると思います。というかもっと基本的なものを作ったらどうかと思う。
確かにおっしゃるとおりです。私は今C#を練習中の身です。普通の画像を表示することなどはできました。ですが、
練習を重ねていくうちにα画像をきれいに表示させたいと思い、現在に至ります。素人の甘い考えだとは存じますが、
コレだけはマスターしたく質問させていただいたしだいです

私も、Google検索などでいろいろ調べ、レイヤードウィンドウの作り方などを調べてはいましたが、必ずといってエラーが出てしまいます。
そのことについても何かアドバイスがありましたらお願いします
引用返信 編集キー/
■64760 / inTopicNo.8)  Re[3]: ピクチャボックスでデスクトップにキャラクター
□投稿者/ Azulean (76回)-(2013/01/05(Sat) 21:20:51)
No64756 (ごりま さん) に返信
> 2.ピクチャボックスをフォームに貼り付けのち親コンテナにドッキング サイズはStretchImage

StretchImage の効用はご存知でしょうか?
ピクチャボックスのサイズに合わせて画像を拡大・縮小しますので、色の補間、すなわち背景色と前景色との中間色が発生するわけです。
試しに Normal にすると、境界色の問題はなくなるのでしょうか?

(現段階では投稿を読んで問題点の指摘というレベルですので、ほかに問題があるかどうかは調べたり、試したりしていません)


No64759 (ごりま さん) に返信
> 私も、Google検索などでいろいろ調べ、レイヤードウィンドウの作り方などを調べてはいましたが、必ずといってエラーが出てしまいます。
> そのことについても何かアドバイスがありましたらお願いします

どういったコードを書いてどのようなエラーが出たのかを伝えず、一般論で質問されてもアドバイスは困難ですよ。
一度、以下のページを読んでいただければ、質問スキルを上げられるかと思います。
メーリングリストを題材にした内容ですが、フォーラム・掲示板などのコミュニティでも活きてきます。

http://www.hyuki.com/writing/techask.html
引用返信 編集キー/
■64761 / inTopicNo.9)  Re[4]: ピクチャボックスでデスクトップにキャラクター
□投稿者/ ごりま (5回)-(2013/01/05(Sat) 21:57:42)
2013/01/05(Sat) 22:05:33 編集(投稿者)
皆さんご回答ありがとうございました。
このたびの質問は皆様のおかげで解決することができました。

解決したソースコードを添付いたします。もっといい方法があるなどございましたらご指摘ください

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            // 境界線を無くす
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
        }


        protected override System.Windows.Forms.CreateParams CreateParams
        {
            get
            {
                const int WS_EX_LAYERED = 0x00080000;

                System.Windows.Forms.CreateParams cp = base.CreateParams;
                cp.ExStyle = cp.ExStyle | WS_EX_LAYERED;

                return cp;
            }
        }


        [DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
        [DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern int DeleteObject(IntPtr hobject);

        public const byte AC_SRC_OVER = 0;
        public const byte AC_SRC_ALPHA = 1;
        public const int ULW_ALPHA = 2;

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct BLENDFUNCTION
        {
            public byte BlendOp;
            public byte BlendFlags;
            public byte SourceConstantAlpha;
            public byte AlphaFormat;
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern int UpdateLayeredWindow(
            IntPtr hwnd,
            IntPtr hdcDst,
            [System.Runtime.InteropServices.In()]
            ref Point pptDst,
            [System.Runtime.InteropServices.In()]
            ref Size psize,
            IntPtr hdcSrc,
            [System.Runtime.InteropServices.In()]
            ref Point pptSrc,
            int crKey,
            [System.Runtime.InteropServices.In()]
            ref BLENDFUNCTION pblend,
            int dwFlags);


        public void SetLayeredWindow(Bitmap srcBitmap)
        {

            Graphics g_sc = Graphics.FromHwnd(IntPtr.Zero);
            IntPtr hdc_sc = g_sc.GetHdc();

            Graphics g_bmp = Graphics.FromImage(srcBitmap);
            IntPtr hdc_bmp = g_bmp.GetHdc();


            IntPtr oldhbmp = SelectObject(hdc_bmp, srcBitmap.GetHbitmap(Color.FromArgb(0)));

            BLENDFUNCTION blend = new BLENDFUNCTION();
            blend.BlendOp = AC_SRC_OVER;
            blend.BlendFlags = 0;
            blend.SourceConstantAlpha = 255;
            blend.AlphaFormat = AC_SRC_ALPHA;


            Point pos = new Point(this.Left, this.Top);

            
            Size surfaceSize = new Size(this.Width, this.Height);

            
            Point surfacePos = new Point(0, 0);

            
            UpdateLayeredWindow(
                this.Handle, hdc_sc, ref pos, ref surfaceSize,
                hdc_bmp, ref surfacePos, 0, ref blend, ULW_ALPHA);

            
            DeleteObject(SelectObject(hdc_bmp, oldhbmp));
            g_sc.ReleaseHdc(hdc_sc);
            g_sc.Dispose();
            g_bmp.ReleaseHdc(hdc_bmp);
            g_bmp.Dispose();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            {
         
                   
                    Bitmap bmp = new Bitmap(Properties.Resources._87);

                    SetLayeredWindow(bmp);
                   
               

            }
        }
    }



まだ他のサイト様を見てまねてみただけであんまり理解はしていないです。


このフォームにピクチャボックスを貼り付けてピクチャボックスの画像をレイヤーウィンドウにするなどできますでしょうか?
また、もし上記のことができない場合、Bitmapで画像を読み込む際にフォームの大きさに合わせてリサイズさせることはできるのでしょうか?
余談ですが、フォームの大きさを変更してデバッグをしたらウィンドウが表示されないなどが発生しました。画像のちょうどいい大きさにしなければいけないのでしょうか・・・でしたら調節が難しいですね・・・

今回お世話になりました皆様ありがとうございました。
またの機械がありましたらよろしくお願いします


参考にさせていただいたサイト
http://www.ipentec.com/document/document.aspx?page=csharp-winform-layerd-window-create
http://amonution.sblo.jp/article/43938587.html

解決済み
引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -