【C#】【Form】PictureBox [7] ~ 画像をコピーする・その1 ~

■ 大きな流れ

【1】 画像上にマウスで矩形を描画
【2】 【1】の領域の画像をクリップボードにコピー

【1】 画像上にマウスで矩形を描画

http://bbs.wankuma.com/index.cgi?mode=al2&namber=60074&KLOG=101
に記載しているロジックでいける
以下の4つのイベントで行う。

 + MouseDown
 + MouseMove
 + MouseUp
 + Paint

【2】 矩形領域の画像をクリップボードにコピー

http://www.atmarkit.co.jp/fdotnet/dotnettips/912bitmapcroprect/bitmapcroprect.html
https://dobon.net/vb/dotnet/graphics/getclipboarddata.html
を組み合わせれば結構簡単にできる

Bitmap image = new Bitmap(this.pictureBox1.Image);
Bitmap selectedImage = image.Clone(this.targetRectangle, image.PixelFormat);
Clipboard.SetImage(selectedImage);

補足:Graphicsで描画した図形も含めてコピーについて

 * Graphicsで描画した図形も含めてコピーする方法について
   以下の関連記事を参照。
PictureBox [7] ~ 画像をコピーする・その2 ~
https://blogs.yahoo.co.jp/dk521123/37941138.html

■ サンプル

例1:矩形で囲ってボタン押下でコピー

コントロール構成
 * button
 * pictureBox
コード
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace SampleForm
{
  public partial class Form1 : Form
  {
    private Nullable<Point> startPoint;
    private Rectangle targetRectangle;

    public Form1()
    {
      InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
      // カーソルを変える
      this.pictureBox1.Cursor = Cursors.Cross;
    }

    private void button1_Click(object sender, EventArgs e)
    {
      using (var image = new Bitmap(this.pictureBox1.Image))
      using (var selectedImage = image.Clone(this.targetRectangle, image.PixelFormat))
      {
        // 画像をクリップボードにコピー
        Clipboard.SetImage(selectedImage);
      }
    }

    private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
    {
      this.startPoint = e.Location;
    }

    private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
    {
      if (this.startPoint == null)
      {
        return;
      }
      var start = this.startPoint.Value;
      var end = e.Location;
      this.targetRectangle = Rectangle.FromLTRB(
          Math.Min(start.X, end.X), Math.Min(start.Y, end.Y),
          Math.Max(start.X, end.X), Math.Max(start.Y, end.Y));
      ((Control)sender).Invalidate();
    }

    private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
    {
      ((Control)sender).Update();
      this.startPoint = null;
    }

    private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
      if (this.startPoint == null)
      {
        return;
      }

      var pen = new Pen(Color.Red, 2)
      {
        DashStyle = DashStyle.Dot
      };
      e.Graphics.DrawRectangle(pen, this.targetRectangle);
    }
  }
}

例2:矩形で囲ってリリースしたタイミングでコピー

コントロール構成
 * pictureBox
コード
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace SampleForm
{
  public partial class Form1 : Form
  {
    private Point startPoint = Point.Empty;
    private Rectangle targetRectangle = Rectangle.Empty;

    public Form1()
    {
      InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
      // カーソルを変える
      this.pictureBox1.Cursor = Cursors.Cross;

      this.startPoint = Point.Empty;
    }

    private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
    {
      if (e.Button != MouseButtons.Left)
      {
        // 右クリックは無視
        return;
      }

      this.startPoint = e.Location;
    }

    private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
    {
      if (this.startPoint.IsEmpty)
      {
        return;
      }

      var start = this.startPoint;
      var end = e.Location;
      this.targetRectangle = Rectangle.FromLTRB(
          Math.Min(start.X, end.X), Math.Min(start.Y, end.Y),
          Math.Max(start.X, end.X), Math.Max(start.Y, end.Y));

      var pictureBox = sender as PictureBox;
      pictureBox.Invalidate();
    }

    private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
    {
      if (this.targetRectangle.Height == 0 || this.targetRectangle.Width == 0)
      {
        return;
      }

      var pictureBox = sender as PictureBox;

      var start = this.startPoint;
      var end = e.Location;
      var copyArea = Rectangle.FromLTRB(
          Math.Min(start.X, end.X), Math.Min(start.Y, end.Y),
          Math.Max(start.X, end.X), Math.Max(start.Y, end.Y));
      using (var image = new Bitmap(pictureBox.Image))
      using (var selectedImage = image.Clone(copyArea, image.PixelFormat))
      {
        // 画像をクリップボードにコピー
        Clipboard.SetImage(selectedImage);
      }

      pictureBox.Invalidate();
      this.startPoint = Point.Empty;
      this.targetRectangle = Rectangle.Empty;
    }

    private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
      if (this.startPoint.IsEmpty)
      {
        return;
      }

      var pen = new Pen(Color.Red, 2)
      {
        DashStyle = DashStyle.Dot
      };
      var graphics = e.Graphics;
      graphics.DrawRectangle(pen, this.targetRectangle);
    }
  }
}


関連記事

PictureBox

PictureBox [1] ~ 画像を表示する ~
https://blogs.yahoo.co.jp/dk521123/23504075.html
PictureBox [2] ~ PictureBox を マウスで移動する ~
https://blogs.yahoo.co.jp/dk521123/37861699.html
PictureBox [3] ~ マウスホイール で画像の拡大・縮小する ~
https://blogs.yahoo.co.jp/dk521123/37866101.html
PictureBox [4] ~ PictureBox 内に文字列を描画する ~
https://blogs.yahoo.co.jp/dk521123/37890831.html
PictureBox [5] ~ PictureBox 内に画像を描画する ~
https://blogs.yahoo.co.jp/dk521123/37890873.html
PictureBox [6] ~ PictureBox 内でMouseMoveイベントにより線を描画する ~
https://blogs.yahoo.co.jp/dk521123/37905014.html
PictureBox [7] ~ 画像をコピーする・その2 ~
https://blogs.yahoo.co.jp/dk521123/37941138.html

画像処理

画像処理 ~ 輝度変更 (明るさ) ~
https://blogs.yahoo.co.jp/dk521123/37844934.html
画像処理 ~ シャープネス ~
https://blogs.yahoo.co.jp/dk521123/37837353.html
画像処理 ~ 回転 ~
https://blogs.yahoo.co.jp/dk521123/37853430.html
画像処理 ~ コントラスト ~
https://blogs.yahoo.co.jp/dk521123/37852480.html

その他

Windows Form ~ 目次 ~
https://blogs.yahoo.co.jp/dk521123/8054245.html
PictureBox ~画像を表示する~
https://blogs.yahoo.co.jp/dk521123/23504075.html
C#】Graphics ~ 図形の描画 ~
https://blogs.yahoo.co.jp/dk521123/32877749.html
C#】図形 ~ 矩形 / Rectangle ~
https://blogs.yahoo.co.jp/dk521123/37888274.html
クリップボード
https://blogs.yahoo.co.jp/dk521123/7518189.html
カーソル
https://blogs.yahoo.co.jp/dk521123/20246067.html