【Winform】透過処理された画像の追加と重ね合わせ

この資料では、Visual Studioを使用して、WinFormsアプリケーションに透過処理された画像ファイルを追加し、それをフォーム上に重ね合わせて描画する方法を説明します。

重ね合わせ表示

ステップ 1: プロジェクトに画像ファイルを追加する

  1. プロジェクトを右クリック
    • ソリューションエクスプローラーでプロジェクト名を右クリックします。
    • 「追加」→「既存の項目」を選択します。
  2. ファイル種類を選択
    • 「項目追加」ダイアログが表示されます。
    • 画像ファイルの種類(*.png, *.jpg, *.gif など)を選択し、追加したい画像ファイルを選択します。
  3. 追加された画像ファイルのプロパティを変更
    • 追加された画像ファイルを右クリックし、「プロパティ」を選択します。
    • 「出力ディレクトリにコピー」の設定を「新しい場合はコピーする」に変更します。

ステップ1の補足

プロジェクトを右クリックのイメージ

ファイル種類を選択のイメージ

画面右下にファイル種別選択のプルダウンメニューがあります

必要な画像を選択

画像がセレクトされますので、選択します

追加された画像ファイルのプロパティを変更

ビルド時に、実行ファイルと同じフォルダにコピーされるようにします
これによりファイルの場所指定で..¥..¥が不要になります

ステップ 2: 透過処理された画像を重ね合わせて描画する

以下のコードを使用して、透過処理された画像をフォームに重ね合わせて描画する方法を説明します。

using System;
using System.Drawing;
using System.Windows.Forms;

namespace TransGraphic
{
    public partial class Form1 : Form
    {
        private Bitmap image1;
        private Bitmap image2;

        public Form1()
        {
            this.Text = "透過PNGイラストの重ね合わせ";
            this.Size = new Size(800, 600);

            // PNGファイルの読み込み
            image1 = new Bitmap("dog.png");
            image2 = new Bitmap("cat.png");

            // ダブルバッファリングを有効にする
            this.DoubleBuffered = true;
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Graphics g = e.Graphics;

            // 画像の描画
            if (image1 != null)
            {
                // ストレッチして描画 (位置とサイズを指定)
                g.DrawImage(image1, new Rectangle(70, 70, 100, 100));
            }

            if (image2 != null)
            {
                // ストレッチして描画 (位置とサイズを指定)
                g.DrawImage(image2, new Rectangle(100, 100, 100, 100));
            }
        }

        protected override void OnFormClosed(FormClosedEventArgs e)
        {
            // リソースの解放
            if (image1 != null)
            {
                image1.Dispose();
            }

            if (image2 != null)
            {
                image2.Dispose();
            }

            base.OnFormClosed(e);
        }
    }
}

説明:

  1. フォームの初期設定
    • Form1 クラスのコンストラクタで、フォームのタイトルとサイズを設定します。
    • 追加した画像ファイル (dog.png と cat.png) を読み込み、Bitmap オブジェクトとして保持します。
  2. ダブルバッファリングの有効化
    • フォームのちらつきを防ぐために、ダブルバッファリングを有効にします。
  3. OnPaint メソッドのオーバーライド
    • OnPaint メソッドをオーバーライドして、透過処理された画像をフォーム上に重ね合わせて描画します。
    • 画像が null でない場合、指定した位置とサイズで描画します。
  4. リソースの解放
    • OnFormClosed メソッドをオーバーライドして、フォームが閉じられたときに画像リソースを解放します。

この方法を使うことで、透過処理された画像を重ね合わせて描画することができます。これにより、複雑なグラフィックを簡単に作成することが可能です。

マウスで移動

この資料では、Visual Studioを使用して、WinFormsアプリケーションに透過処理された画像ファイルを追加し、それをフォーム上に重ね合わせて描画し、さらにカーソルで画像を移動できるようにする方法を説明します。

ステップ 1: プロジェクトに画像ファイルを追加する

  1. プロジェクトを右クリック
    • ソリューションエクスプローラーでプロジェクト名を右クリックします。
    • 「追加」→「既存の項目」を選択します。
  2. ファイル種類を選択
    • 「項目追加」ダイアログが表示されます。
    • 画像ファイルの種類(*.png, *.jpg, *.gif など)を選択し、追加したい画像ファイルを選択します。
  3. 追加された画像ファイルのプロパティを変更
    • 追加された画像ファイルを右クリックし、「プロパティ」を選択します。
    • 「出力ディレクトリにコピー」の設定を「新しい場合はコピーする」に変更します。

ステップ 2: 透過処理された画像を重ね合わせて描画し、カーソルで移動可能にする

以下のコードを使用して、透過処理された画像をフォームに重ね合わせて描画し、カーソルで画像を移動できるようにする方法を説明します。

using System;
using System.Drawing;
using System.Windows.Forms;

namespace TransGraphic
{
    public partial class Form1 : Form
    {
        private Bitmap image1;
        private Bitmap image2;
        private Point image1Position;
        private Point image2Position;
        private bool isDraggingImage1 = false;
        private bool isDraggingImage2 = false;
        private Point dragOffset;

        public Form1()
        {
            this.Text = "透過PNGイラストの重ね合わせと移動";
            this.Size = new Size(800, 600);

            // PNGファイルの読み込み
            image1 = new Bitmap("dog.png");
            image2 = new Bitmap("cat.png");

            // 初期位置の設定
            image1Position = new Point(70, 70);
            image2Position = new Point(100, 100);

            // ダブルバッファリングを有効にする
            this.DoubleBuffered = true;

            // マウスイベントハンドラの追加
            this.MouseDown += Form1_MouseDown;
            this.MouseMove += Form1_MouseMove;
            this.MouseUp += Form1_MouseUp;
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Graphics g = e.Graphics;

            // 画像の描画
            if (image1 != null)
            {
                g.DrawImage(image1, new Rectangle(image1Position.X, image1Position.Y, 100, 100));
            }

            if (image2 != null)
            {
                g.DrawImage(image2, new Rectangle(image2Position.X, image2Position.Y, 100, 100));
            }
        }

        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            if (IsMouseOnImage(image1, image1Position, e.Location))
            {
                isDraggingImage1 = true;
                dragOffset = new Point(e.Location.X - image1Position.X, e.Location.Y - image1Position.Y);
            }
            else if (IsMouseOnImage(image2, image2Position, e.Location))
            {
                isDraggingImage2 = true;
                dragOffset = new Point(e.Location.X - image2Position.X, e.Location.Y - image2Position.Y);
            }
        }

        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            if (isDraggingImage1)
            {
                image1Position = new Point(e.Location.X - dragOffset.X, e.Location.Y - dragOffset.Y);
                this.Invalidate();
            }
            else if (isDraggingImage2)
            {
                image2Position = new Point(e.Location.X - dragOffset.X, e.Location.Y - dragOffset.Y);
                this.Invalidate();
            }
        }

        private void Form1_MouseUp(object sender, MouseEventArgs e)
        {
            isDraggingImage1 = false;
            isDraggingImage2 = false;
        }

        private bool IsMouseOnImage(Bitmap image, Point imagePosition, Point mousePosition)
        {
            Rectangle imageRect = new Rectangle(imagePosition, new Size(100, 100));
            return imageRect.Contains(mousePosition);
        }

        protected override void OnFormClosed(FormClosedEventArgs e)
        {
            // リソースの解放
            if (image1 != null)
            {
                image1.Dispose();
            }

            if (image2 != null)
            {
                image2.Dispose();
            }

            base.OnFormClosed(e);
        }
    }
}

説明:

  1. フォームの初期設定
    • Form1 クラスのコンストラクタで、フォームのタイトルとサイズを設定します。
    • 追加した画像ファイル (dog.png と cat.png) を読み込み、Bitmap オブジェクトとして保持します。
    • 画像の初期位置を設定します。
  2. ダブルバッファリングの有効化
    • フォームのちらつきを防ぐために、ダブルバッファリングを有効にします。
  3. マウスイベントハンドラの追加
    • フォームのマウスイベント (MouseDownMouseMoveMouseUp) を処理するハンドラを追加します。
  4. 画像の描画
    • OnPaint メソッドをオーバーライドして、透過処理された画像をフォーム上に重ね合わせて描画します。
  5. 画像のドラッグ
    • マウスダウン時に、クリック位置が画像上であればドラッグを開始します。
    • マウス移動時に、ドラッグ中の画像の位置を更新します。
    • マウスアップ時に、ドラッグを終了します。
  6. リソースの解放
    • OnFormClosed メソッドをオーバーライドして、フォームが閉じられたときに画像リソースを解放します。

これで、透過処理された画像を重ね合わせて描画し、カーソルで画像を移動できるWinFormsアプリケーションを作成する方法が理解できたと思います。

画像のドラッグと位置計算

位置計算の詳細

イメージの表示座標とマウスカーソルの座標には差があります
描画の時に、この差分を考慮する必要があります

初期位置の設定

image1Position = new Point(70, 70);
image2Position = new Point(100, 100);
  • 画像1(犬)と画像2(猫)の初期位置をPointオブジェクトで設定します。
  • Pointオブジェクトは2D空間の座標(x, y)を保持します。

マウスダウンイベント

private void Form1_MouseDown(object sender, MouseEventArgs e)
{
    if (IsMouseOnImage(image1, image1Position, e.Location))
    {
        isDraggingImage1 = true;
        dragOffset = new Point(e.Location.X - image1Position.X, e.Location.Y - image1Position.Y);
    }
    else if (IsMouseOnImage(image2, image2Position, e.Location))
    {
        isDraggingImage2 = true;
        dragOffset = new Point(e.Location.X - image2Position.X, e.Location.Y - image2Position.Y);
    }
}
  • マウスボタンが押されたときに、マウスカーソルが画像の上にあるかどうかを判定します。
  • 画像の上にあれば、その画像をドラッグ中の状態にし、ドラッグのオフセット(マウス位置と画像位置の差)を計算します。

マウスムーブイベント

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
    if (isDraggingImage1)
    {
        image1Position = new Point(e.Location.X - dragOffset.X, e.Location.Y - dragOffset.Y);
        this.Invalidate();
    }
    else if (isDraggingImage2)
    {
        image2Position = new Point(e.Location.X - dragOffset.X, e.Location.Y - dragOffset.Y);
        this.Invalidate();
    }
}
  • マウスが移動したときに、ドラッグ中の画像の位置を更新します。
  • 新しい位置は、現在のマウス位置からドラッグのオフセットを引いた座標です。
  • Invalidateメソッドを呼び出してフォームを再描画し、新しい位置に画像を表示します。

マウスアップイベント

private void Form1_MouseUp(object sender, MouseEventArgs e)
{
    isDraggingImage1 = false;
    isDraggingImage2 = false;
}
  • マウスボタンが離されたときに、ドラッグ状態を解除します。

画像上のマウス判定

private bool IsMouseOnImage(Bitmap image, Point imagePosition, Point mousePosition)
{
    Rectangle imageRect = new Rectangle(imagePosition, new Size(100, 100));
    return imageRect.Contains(mousePosition);
}
  • Rectangleオブジェクトを使用して、画像の位置とサイズを指定します。
  • マウス位置がこの矩形内にあるかどうかを判定します。

まとめ

  • 位置の管理Pointオブジェクトを使用して画像の位置を管理します。
  • 位置の更新: マウスイベントを通じて画像の位置を更新し、Invalidateメソッドでフォームを再描画します。
  • 位置の計算: 画像の新しい位置は、マウスの現在位置からドラッグのオフセットを引くことで計算します。

この資料を通じて、画像のドラッグ操作や位置計算の基本を理解することで、さまざまな応用が可能になります。


protected override void OnPaint(PaintEventArgs e)ですが、 このメソッド(イベントハンドラ)を記述すると、Paintイベントに紐付けなくても良いのか?

はい、protected override void OnPaint(PaintEventArgs e) メソッドをオーバーライドすることで、Paint イベントに紐付ける必要はありません。OnPaint メソッドは、Paint イベントが発生したときに自動的に呼び出されます。

protected override void OnFormClosed(FormClosedEventArgs e) も同様の理由で使用します。これにより、FormClosed イベントに対するカスタム処理を行うことができます。OnFormClosed メソッドをオーバーライドすることで、フォームが閉じられたときに特定の処理を実行できます。この場合、リソースの解放が主な目的です。

C#,VisualStudio

Posted by hidepon