C# Programming

ImageGDI+ (画像のクリッピングとRegion)

開発環境: Visual Studio 2003

画像のクリッピング

画像をクリッピングする。

System.Drawing.Drawing2D.FillMode.Alternate;
Alternate(交互)塗りつぶしモード


Image

System.Drawing.Drawing2D.FillMode.Winding;
Winding 塗りつぶしモード


Image

作り方

1. 4-1 ImageViewer を作る。
2. クリッピングするためのメソッド SetRegion() を追加する。
3, 画像呼び出し時に SetRegion()を呼び出す。

SetRegionの説明

星を書くために、ちょっと余計なことをしていますが、基本形は

System.Drawing.Drawing2D.GraphicsPath gPath = new System.Drawing.Drawing2D.GraphicsPath();
gPath.FillMode = System.Drawing.Drawing2D.FillMode.Alternate;      // FillModeの設定。
gPath.AddLine(....);                                                                 // AddLineなどのパス構築メソッド。
this.pictureBox1.Region = new Region(gPath);                              // PathからRegion を生成し、ウィンドウに適用する。

注意: FillMode はデフォルトで FillMode.Alternate

Formのクリッピング

同様に、Form そのものにRegion を適用すると、次のようにメインウィンドウそのものをクリッピングできる。
3-3 自由図形のアナログクロックを作る。   とは違ってGraphicsPath を使ってできるので、Pathがはっきりわかっているような場合に使えるでしょう。

Image

日付 修正履歴
2002/5/11 初期バージョン作成
2003/5/25 メニューから、リージョンをセット、リセットできるように変更
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace ImageBrowser
{
        /// <summary>
        /// Form1 の概要の説明です。
        /// </summary>
        public class ImageViewer : System.Windows.Forms.Form
        {
                private System.Windows.Forms.MainMenu mainMenu1;
                private System.Windows.Forms.MenuItem menuOpen;
                private System.Windows.Forms.MenuItem menuFile;
                private System.Windows.Forms.MenuItem menuClose;
                /// <summary>
                /// 必要なデザイナ変数です。
                /// </summary>
                private System.ComponentModel.Container components = null;
                private System.Windows.Forms.PictureBox pictureBox1;
        private System.Windows.Forms.MenuItem menuItem1;
        private System.Windows.Forms.MenuItem menuItem2;
                private string fileName = null;

                public ImageViewer()
                {
                        //
                        // Windows フォーム デザイナ サポートに必要です。
                        //
                        InitializeComponent();

                        //
                        // TODO: InitializeComponent 呼び出しの後に、コンストラクタ コードを追加してください。
                        //
                }

                /// <summary>
                /// 使用されているリソースに後処理を実行します。
                /// </summary>
                protected override void Dispose( bool disposing )
                {
                        if( disposing )
                        {
                                if (components != null) 
                                {
                                        components.Dispose();
                                }
                        }
                        base.Dispose( disposing );
                }

                #region Windows Form Designer generated code
                /// <summary>
                /// デザイナ サポートに必要です。このメソッドの内容を
                /// コード エディタで変更しないでください。
                /// </summary>
                private void InitializeComponent()
                {
            this.menuClose = new System.Windows.Forms.MenuItem();
            this.menuOpen = new System.Windows.Forms.MenuItem();
            this.menuFile = new System.Windows.Forms.MenuItem();
            this.mainMenu1 = new System.Windows.Forms.MainMenu();
            this.pictureBox1 = new System.Windows.Forms.PictureBox();
            this.menuItem1 = new System.Windows.Forms.MenuItem();
            this.menuItem2 = new System.Windows.Forms.MenuItem();
            this.SuspendLayout();
            // 
            // menuClose
            // 
            this.menuClose.Index = 3;
            this.menuClose.Text = "終了(&X)";
            this.menuClose.Click += new System.EventHandler(this.OnClose);
            // 
            // menuOpen
            // 
            this.menuOpen.Index = 0;
            this.menuOpen.Text = "開く(&O)";
            this.menuOpen.Click += new System.EventHandler(this.OnMenuOpen);
            // 
            // menuFile
            // 
            this.menuFile.Index = 0;
            this.menuFile.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
                                                                                     this.menuOpen,
                                                                                     this.menuItem2,
                                                                                     this.menuItem1,
                                                                                     this.menuClose});
            this.menuFile.Text = "ファイル(&F)";
            // 
            // mainMenu1
            // 
            this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
                                                                                      this.menuFile});
            // 
            // pictureBox1
            // 
            this.pictureBox1.Name = "pictureBox1";
            this.pictureBox1.Size = new System.Drawing.Size(208, 142);
            this.pictureBox1.TabIndex = 0;
            this.pictureBox1.TabStop = false;
            this.pictureBox1.Paint += new System.Windows.Forms.PaintEventHandler(this.OnPaint);
            // 
            // menuItem1
            // 
            this.menuItem1.Index = 2;
            this.menuItem1.Text = "リージョンのリセット";
            this.menuItem1.Click += new System.EventHandler(this.menuItem1_Click);
            // 
            // menuItem2
            // 
            this.menuItem2.Index = 1;
            this.menuItem2.Text = "リージョンのセット";
            this.menuItem2.Click += new System.EventHandler(this.menuItem2_Click);
            // 
            // ImageViewer
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
            this.ClientSize = new System.Drawing.Size(292, 245);
            this.Controls.AddRange(new System.Windows.Forms.Control[] {
                                                                          this.pictureBox1});
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D;
            this.Menu = this.mainMenu1;
            this.Name = "ImageViewer";
            this.Text = "ImageViewer";
            this.ResumeLayout(false);

        }
                #endregion

                /// <summary>
                /// アプリケーションのメイン エントリ ポイントです。
                /// </summary>
                [STAThread]
                static void Main() 
                {
                        Application.Run(new ImageViewer());
                }

                private void OnMenuOpen(object sender, System.EventArgs e)
                {
                        OpenFileDialog openFileDialog1 = new OpenFileDialog();

                        openFileDialog1.InitialDirectory = "c:\\" ;
                        openFileDialog1.Filter = "JPEG files (*.jpg)|*.jpg|GIF files (*.gif)|*.gif|Bitmap files (*.bmp)|*.bmp|All files (*.*)|*.*" ;
                        openFileDialog1.FilterIndex = 1 ;
                        openFileDialog1.RestoreDirectory = true ;

                        if(openFileDialog1.ShowDialog() == DialogResult.OK)
                        {
                                fileName = openFileDialog1.FileName;
                                this.pictureBox1.Invalidate();
                        }
                }

                private void DrawImage(Graphics g)
                {
                        try 
                        {       
                                Bitmap myBitmap = new Bitmap( fileName );
                                this.pictureBox1.Width = myBitmap.Width;
                                this.pictureBox1.Height = myBitmap.Height;
                                // Fit form to the image size.
                                this.SetClientSizeCore(this.pictureBox1.Width, this.pictureBox1.Height);

                                g.DrawImage( myBitmap, this.ClientRectangle );

                        } 
                        catch ( System.ArgumentException e)
                        {
                                MessageBox.Show(e.Message + "\n画像ファイルを選択してください。", this.Text,
                                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                }

                private void OnClose(object sender, System.EventArgs e)
                {
                        Close();
                }

                private void OnPaint(object sender, System.Windows.Forms.PaintEventArgs e)
                {
                        if ( fileName != null ) 
                                DrawImage(e.Graphics);
                }

                private void SetRegion()
                {
                        System.Drawing.Drawing2D.GraphicsPath gPath = new System.Drawing.Drawing2D.GraphicsPath();
                        int r = System.Math.Min(this.pictureBox1.Width, this.pictureBox1.Height)/2;

                        Point[] points = 
                        {
                                new Point((int)(r*Math.Sin(Math.PI*2*0.0)), (int)(r*-Math.Cos(Math.PI*2*0))),
                                new Point((int)(r*Math.Sin(Math.PI*2*1/5)), (int)(r*-Math.Cos(Math.PI*2*1/5))),
                                new Point((int)(r*Math.Sin(Math.PI*2*2/5)), (int)(r*-Math.Cos(Math.PI*2*2/5))),
                                new Point((int)(r*Math.Sin(Math.PI*2*3/5)), (int)(r*-Math.Cos(Math.PI*2*3/5))),
                                new Point((int)(r*Math.Sin(Math.PI*2*4/5)), (int)(r*-Math.Cos(Math.PI*2*4/5))),
                    };

                        gPath.FillMode = System.Drawing.Drawing2D.FillMode.Winding;
                        gPath.AddLine(points[0], points[2]);
                        gPath.AddLine(points[2], points[4]);
                        gPath.AddLine(points[4], points[1]);
                        gPath.AddLine(points[1], points[3]);
                        gPath.AddLine(points[3], points[0]);

                        gPath.Transform(new System.Drawing.Drawing2D.Matrix(1,0,0,1,r,r));
                        this.pictureBox1.Region = new Region(gPath);
                }

        private void menuItem1_Click(object sender, System.EventArgs e)
        {
            this.pictureBox1.Region = null;
        }

        private void menuItem2_Click(object sender, System.EventArgs e)
        {
            // リージョンの設定。
            this.SetRegion();
        }
        }
}