ドラッグするだけでWeb上の画像を保存できるようにするプログラムを作成します。
実はウェブ上の画像をドラッグで素早く保存する方法はあります。
ウェブ上の画像をドラッグで素早く保存 – 初心者・シニア向パソコン教室用テキスト「ハッピーテキスト」
単にブラウザから保存したい場所(フォルダ、デスクトップ)にドラッグするだけです。こんな簡単な方法で保存できます。
ただこの場合は画像ファイルをまるごと保存するときには便利ですが、画像の一部だけがほしいときはちょっと面倒です。そこでWeb上の画像のうち、ドラッグされた部分だけを画像として保存できるアプリをつくってみることにします。
アプリの外でドラッグ&ドロップを検出する方法としてマウスキャプチャがあります。この方法だとマウスがフォームの外にでてしまってもマウスメッセージは指定されたフォームに届きます。 しかしこれには制限があってボタンが押されているのみ有効です。
マウスキャプチャをしたらそれを解除する手段も用意しておかなければなりません。もしマウスキャプチャが無制限にできてしまうと、それを解除できなくなってしまったときに他のアプリケーションでマウスをクリックしてもなにもおきなくなるという問題がおきます。それでいろいろ制約があるのでしょう。
ではフォームの外へでている状態でマウスボタンがおされて離されたことを知るにはどうすればよいのでしょうか?
スクリーン全体を透明なフォームで覆ってしまうというのはどうでしょうか? これならもともとフォーム内なのでマウスの移動、クリックなどを知ることができます。
まずフォームを2つ作ります(Form1とForm2)。
そして[キャプチャしたい部分を指定する]のボタンがクリックされたら
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public partial class Form1 : Form { Form2 f = new Form2(); private void button1_Click(object sender, EventArgs e) { f.Opacity = 0.5; f.StartPosition = FormStartPosition.Manual; f.Location = new Point(0, 0); f.Size = new Size(Screen.PrimaryScreen.WorkingArea.Width, Screen.PrimaryScreen.WorkingArea.Height); f.ShowDialog(); Form2Closed(); } void Form2Closed() { // Form2が閉じられたときの処理 } } |
これで半透明のフォームでディスプレイ全体を覆うことができます。
次にForm2において
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
public partial class Form2 : Form { int x1 = -1; int y1 = -1; public Rectangle Rectangle; bool isMouseDown = false; public Form2() { InitializeComponent(); MouseDown += Form2_MouseDown; MouseMove += Form2_MouseMove; Paint += Form2_Paint; MouseUp += Form2_MouseUp; } private void Form2_Load(object sender, EventArgs e) { x1 = -1; y1 = -1; Rectangle = new Rectangle(); } private void Form2_MouseDown(object sender, MouseEventArgs e) { isMouseDown = true; x1 = Control.MousePosition.X; y1 = Control.MousePosition.Y; } private void Form2_MouseMove(object sender, MouseEventArgs e) { Cursor.Current = Cursors.Cross; if(isMouseDown) { Invalidate(); } } private void Form2_Paint(object sender, PaintEventArgs e) { int x2 = Control.MousePosition.X; int y2 = Control.MousePosition.Y; if(x1 == -1) return; Point pt1 = this.PointToClient(new Point(x1, y1)); Point pt2 = this.PointToClient(new Point(x2, y2)); Rectangle rect = GetRectangle(pt1, pt2); e.Graphics.DrawRectangle(new Pen(Color.Black), rect); } private void Form2_MouseUp(object sender, MouseEventArgs e) { int x = Control.MousePosition.X; int y = Control.MousePosition.Y; Rectangle = GetRectangle(new Point(x1, y1), new Point(x, y)); Close(); } } |
これでマウスをクリックしてドラッグするとクリックされた場所を起点に矩形が描画されます。そしてドロップするとフォームが閉じます。
つぎにForm2を表示させる部分を示します。まずForm2のTopMostプロパティをtrueにします。そうしないとアクティブなウィンドウを切り替えたときにForm2が最前面ではなくなってしまいます。またこのときにはForm1も透明にします。
Form2が閉じられたらドラッグされた部分の画像を保存する処理を行ないます。これはForm2Closedメソッドのなかでおこないます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
public partial class Form1 : Form { Form2 f = new Form2(); private void button1_Click(object sender, EventArgs e) { this.Opacity = 0.0; // 自分自身を透明にする f.Opacity = 0.5; f.TopMost = true; f.StartPosition = FormStartPosition.Manual; f.Location = new Point(0, 0); f.Size = new Size(Screen.PrimaryScreen.WorkingArea.Width, Screen.PrimaryScreen.WorkingArea.Height); f.ShowDialog(); Form2Closed(); this.Opacity = 1.0; // 終わったらもとに戻す } void Form2Closed() { // Form2が閉じられたときの処理 } } |
Form2Closedメソッドが呼ばれたときになにをするかですが、
スクリーンキャプチャをする
Form2のなかでつくられた矩形の部分を画像として保存する
これでよいということになります。
まずスクリーンキャプチャをするメソッドを示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public partial class Form1 : Form { private Bitmap ScreenCapture() { Bitmap bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); Graphics g = Graphics.FromImage(bmp); //画面全体をコピーする g.CopyFromScreen(new Point(0, 0), new Point(0, 0), bmp.Size); g.Dispose(); return bmp; } } |
つぎにトリミングをするメソッドを示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public partial class Form1 : Form { Bitmap Trim(Bitmap srcBitmap, Rectangle rect) { Bitmap bitmap = new Bitmap(rect.Width, rect.Height); Graphics g = Graphics.FromImage(bitmap); Rectangle destRect = new Rectangle(0, 0, rect.Width, rect.Height); g.DrawImage(srcBitmap, destRect, rect.X, rect.Y, rect.Width, rect.Height, GraphicsUnit.Pixel); g.Dispose(); return bitmap; } } |
上記のメソッドで取得されたビットマップを保存すれば完成です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
public partial class Form1 : Form { void Form2Closed() { // 幅または高さがゼロのときはなにもしない。 if(rect.Width == 0 || rect.Height == 0) return; using(Bitmap srcBitmap = ScreenCapture()) using(Bitmap bmp = Trim(srcBitmap, rect)) SaveBitmap(bmp); // 適当な名前をつけて保存する } void SaveBitmap(Bitmap bmp) { string folderPath = Application.StartupPath + "\\png"; if(!System.IO.Directory.Exists(folderPath)) System.IO.Directory.CreateDirectory(folderPath); DateTime dt = DateTime.Now; string fileName = dt.Ticks.ToString(); bmp.Save(folderPath + "\\" + fileName + ".png", System.Drawing.Imaging.ImageFormat.Png); } } |
ファイル形式はPNG、保存場所は実行ファイルがあるフォルダのなかにpngというフォルダをつくって、そのなかに保存しています。ファイル名は時刻を利用しています。