C#で作ってみた 画像切り取り

どんな画像編集ツールにもだいたい備わっている機能を作ってみました。

「画像を範囲指定して切り取る」だけのツールです。

↑画面イメージです。画像上で範囲指定して「画像切取り」ボタンを押すだけの機能です。
以下が処理部のソースコードです。
実行ファイルが欲しい方やすべてのソースコードを参考にしたい方は
最下部からダウンロードしてください。
using System;
using System.Drawing;
using System.Windows.Forms;

namespace PictureCut
{
    public partial class Form1 : Form
    {
        private Rectangle rect;
        private bool blnCut = false;

        public Form1()
        {
            InitializeComponent();
            //ボタンは押下不可にする
            btnCut.Enabled = false;
            btnSave.Enabled = false;
        }

        private void btnOpen_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog()
            {
                Filter = "PNG(*.png)|*.png|JPEG(*.jpg;*.jpeg)|*.jpg;*.jpeg|Bitmap(*.bmp)|*.bmp",
                Multiselect = false,
                RestoreDirectory = true
            };
            if(dlg.ShowDialog() == DialogResult.OK)
            {
                //画像を読み込む
                txtImagePath.Text = dlg.FileName;
                Image img = Image.FromFile(dlg.FileName);
                pictureBox1.Image = img;
                pictureBox1.Size = img.Size;

                //画像が読み込まれていればボタンを押下可にする
                btnSave.Enabled = true;
            }
            dlg.Dispose();
        }

        private void btnCut_Click(object sender, EventArgs e)
        {
            if (rect.Width > 0 && rect.Height > 0)
            {
                try
                {
                    // 画像を切り取りサイズにする
                    Bitmap bmp = new Bitmap(rect.Width, rect.Height);
                    Graphics grp = Graphics.FromImage(bmp);
                    Bitmap pict = new Bitmap(pictureBox1.Image);
                    // 画像を表示
                    grp.DrawImage(pict, new Rectangle(0, 0, rect.Width, rect.Height),
                        rect, GraphicsUnit.Pixel);
                    grp.Dispose();
                    pictureBox1.Image = bmp;
                    pictureBox1.Size = bmp.Size;
                    // 切り取りサイズをクリアし、切り取りボタンを押下不可にする
                    rect.Width = 0;
                    rect.Height = 0;
                    btnCut.Enabled = false;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

        /// <summary>
        /// 四角描画
        /// </summary>
        /// <param name="e"></param>
        private void DrawRect(MouseEventArgs e)
        {
            Graphics grp = pictureBox1.CreateGraphics();
            //青の破線に設定する
            Pen pBox = new Pen(Color.Blue, 1);
            pBox.DashStyle = System.Drawing.Drawing2D.DashStyle.DashDot;
            //描画領域をリフレッシュして線を引く
            pictureBox1.Refresh();
            //開始地点より終了地点が前の場合、座標を入れ替えて四角を表示
            rect.Width = Math.Abs(e.X - rect.X);
            rect.Height = Math.Abs(e.Y - rect.Y);
            grp.DrawRectangle(pBox,
                (e.X < rect.X) ? e.X : rect.X,
                (e.Y < rect.Y) ? e.Y : rect.Y,
                rect.Width,
                rect.Height);
            grp.Dispose();
        }

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            if(e.Button == MouseButtons.Left)
            {
                blnCut = true;
                // 開始地点を記録する
                rect = new Rectangle(e.X, e.Y, 0, 0);
            }
        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if(e.Button == MouseButtons.Left && blnCut)
            {
                //四角形を描く
                DrawRect(e);
            }
        }

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            if(e.Button == MouseButtons.Left && blnCut)
            {
                //四角形を描く
                DrawRect(e);
                //開始地点より終了地点が前の場合、座標を入れ替える
                if (e.X < rect.X)
                {
                    rect.X = e.X;
                }
                if (e.Y < rect.Y)
                {
                    rect.Y = e.Y;
                }
                // 範囲指定の有無で切り取りボタンの押下有無を切り替える
                if (rect.Width > 0 && rect.Height > 0)
                {
                    btnCut.Enabled = true;
                } else
                {
                    btnCut.Enabled = false;
                }

                blnCut = false;
            }
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            SaveFileDialog dlg = new SaveFileDialog()
            {
                Filter = "PNG(*.png)|*.png|JPEG(*.jpg;*.jpeg)|*.jpg;*.jpeg|Bitmap(*.bmp)|*.bmp",
                AddExtension = true,
                DefaultExt = ".png",
                RestoreDirectory = true,
                OverwritePrompt = true
            };
            if(dlg.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    txtImagePath.Text = dlg.FileName;
                    Image img = pictureBox1.Image;
                    System.IO.FileInfo fileInfo = new System.IO.FileInfo(dlg.FileName);
                    // 拡張子に応じたフォーマットで保存する
                    if (".png".Equals(fileInfo.Extension.ToLower()))
                    {
                        img.Save(dlg.FileName, System.Drawing.Imaging.ImageFormat.Png);
                    }
                    else if (".jpg".Equals(fileInfo.Extension.ToLower()) || ".jpeg".Equals(fileInfo.Extension.ToLower()))
                    {
                        img.Save(dlg.FileName, System.Drawing.Imaging.ImageFormat.Jpeg);
                    }
                    else if (".bmp".Equals(fileInfo.Extension.ToLower()))
                    {
                        img.Save(dlg.FileName, System.Drawing.Imaging.ImageFormat.Bmp);
                    }
                } catch(Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            dlg.Dispose();
        }
    }
}

上記は、ソリューション含むすべてのソースコード+実行ファイルです。

ソースコードはダウンロードして、いくら改変していただいてもかまいませんが、改変元のプログラムが原因でいかなる問題が発生したとしても、筆者は責任を負いかねますのでご了承ください。

タイトルとURLをコピーしました