簡易画像編集ソフトをつくる
これまで
画像の拡大と縮小
色の置換と反転
上下左右の反転
文字を入れる
といった処理をするアプリを作成してきました。
今回はこれらを総合的にできるアプリの作成を目指します。Windowsに付属しているペイントで充分ではないのかと思われるかもしれませんが、自分自身のスキル向上のために作成します。
画像を表示させるユーザーコントロールを作成する
画像を編集する以上、画像ファイルを開く処理が必要です。
デザイナでユーザーコントロールを作成します。ピクチャーボックスにスクロールバーがくっついています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public partial class UserControlImage : UserControl { public UserControlImage() { InitializeComponent(); // スクロールバーがスクロールされたときのイベントハンドラ this.vScrollBar1.Scroll += VScrollBar1_Scroll; this.hScrollBar1.Scroll += HScrollBar1_Scroll; // コントロールがリサイズされたときのイベントハンドラ this.Resize += UserControlImage_Resize; this.pictureBox1.Paint += PictureBox1_Paint; } } |
コントロールがリサイズされたとき、ピクチャーボックスになにかが描画されたときはスクロールバーの状態も変更しなければならない場合があります。OptimizationScrloolBarはそのためのメソッドです。
ShowBitmapメソッドはスクロールバーの状態から元画像のトリミングすべき領域をトリミングしてこれを表示させるメソッドです。
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 |
public partial class UserControlImage : UserControl { void OptimizationScrloolBar() { // 横スクロールバーの初期位置、最小値、最大値を設定 hScrollBar1.Minimum = 0; if(Bitmap.Width - pictureBox1.Width >= 0) { int largeChange = pictureBox1.Width * pictureBox1.Width / Bitmap.Width; hScrollBar1.LargeChange = largeChange; hScrollBar1.Maximum = Bitmap.Width - pictureBox1.Width + largeChange; } else hScrollBar1.Maximum = 0; // 縦スクロールバーと横スクロールバーの初期位置、最小値、最大値を設定する vScrollBar1.Minimum = 0; if(Bitmap.Height - pictureBox1.Height >= 0) { int largeChange = pictureBox1.Height * pictureBox1.Height / Bitmap.Height; vScrollBar1.LargeChange = largeChange; vScrollBar1.Maximum = Bitmap.Height - pictureBox1.Height + largeChange; } else vScrollBar1.Maximum = 0; } private void UserControlImage_Resize(object sender, EventArgs e) { if(Bitmap == null) return; // 最小化した場合、pictureBox1のサイズもゼロになる。 // そのときShowBitmapメソッドを実行すると例外が発生するので注意が必要 if(pictureBox1.Width != 0) ShowBitmap(Bitmap); } public void ShowBitmap(Bitmap bitmap) { OptimizationScrloolBar(); // スクロールバー位置より元画像をトリミングして表示する Bitmap bitmap1 = GetBitmapDrawPictureBox(bitmap); pictureBox1.SizeMode = PictureBoxSizeMode.Normal; pictureBox1.Image = bitmap1; } // 編集中のビットマップ public Bitmap Bitmap { get; set; } } |
縦横のスクロールバーでスクロールがおこなわれた場合、ピクチャーボックスに描画される画像を変更する必要があります。そのためShowBitmapメソッドで描画しなおしています。
GetBitmapDrawPictureBoxメソッドはスクロールバー位置より元画像をトリミングして取得するためのものです。以下のようになっています。
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 |
public partial class UserControlImage : UserControl { Bitmap GetBitmapDrawPictureBox(Bitmap bitmap) { Bitmap newBitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height); RectangleF rectSrc = new RectangleF( this.hScrollBar1.Value, this.vScrollBar1.Value, this.pictureBox1.Width, this.pictureBox1.Height); Graphics g = Graphics.FromImage(newBitmap); g.DrawImage(bitmap, 0, 0, rectSrc, GraphicsUnit.Pixel); g.Dispose(); return newBitmap; } private void VScrollBar1_Scroll(object sender, ScrollEventArgs e) { ShowBitmap(bitmap); } private void HScrollBar1_Scroll(object sender, ScrollEventArgs e) { ShowBitmap(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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
public partial class Form1 : Form { // 現在編集中の画像ファイルのパス // 上書き保存するときに必要になる string filePath = ""; public Form1() { InitializeComponent(); ShowInitBitmap(); } // 最初は白色で200×200のビットマップを表示する void ShowInitBitmap() { Bitmap bmp = new Bitmap(200, 200); Graphics g = Graphics.FromImage(bmp); g.Clear(Color.White); g.Dispose(); userControlImage1.Bitmap = bmp; userControlImage1.ShowBitmap(bmp); } private void OpenFileMenuItem_Click(object sender, EventArgs e) { OpenFile(); } void OpenFile() { OpenFileDialog dlg = new OpenFileDialog(); dlg.CheckFileExists = true; dlg.CheckPathExists = true; dlg.Filter = "画像ファイル(*.bmp; *.jpg; *.png)|*.bmp; *.jpg; *.png|すべてのファイル(*.*)|*.*"; if(dlg.ShowDialog() == DialogResult.OK) { if(userControlImage1.LoadImageFile(dlg.FileName)) { // 読み込みに成功したら上書き保存できるようにパスを保存しておく filePath = dlg.FileName; CheckMenu1(SelectionMenuItem); } } dlg.Dispose(); } } |
UserControlImageクラスのLoadImageFileメソッドはこのようになっています。
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 |
public partial class UserControlImage : UserControl { public bool LoadImageFile(string filePath) { Image image; try { image = Image.FromFile(filePath); } catch { return false; } // 以前編集していたBitmapが存在するならDisposeする if(Bitmap != null) { Bitmap.Dispose(); _bitmap = null; } // ファイルがロックされないようにする Bitmap = new Bitmap(image); image.Dispose(); Init(); ShowBitmap(Bitmap); return true; } public void Init() { // スクロールに関する値をリセット ClearScrollInfo(); } } |
ClearScrollInfoメソッドはスクロールをリセットするためのメソッドです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public partial class UserControlImage : UserControl { public void ClearScrollInfo() { ScrollBarPosX = 0; ScrollBarPosY = 0; } // スクロールバーのスクロールを変更するプロパティ public int ScrollBarPosX { get { return hScrollBar1.Value; } set { hScrollBar1.Value = value; } } public int ScrollBarPosY { get { return vScrollBar1.Value; } set { vScrollBar1.Value = value; } } } |
画像を保存する処理
[別名で保存]がクリックされたら名前をつけて画像ファイルを保存することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public partial class Form1 : Form { private void SaveAsFileMenuItem_Click(object sender, EventArgs e) { SaveAsFile(); } void SaveAsFile() { SaveFileDialog dlg = new SaveFileDialog(); dlg.Filter = "画像ファイル(*.bmp)|*.bmp|画像ファイル(*.jpg)|*.jpg|画像ファイル(*.png)|*.png|すべてのファイル(*.*)|*.*"; if(dlg.ShowDialog() == DialogResult.OK) { userControlImage1.Bitmap.Save(dlg.FileName); //上書き保存できるようにパスを保存しておく filePath = dlg.FileName; } dlg.Dispose(); } } |
[上書き保存]がクリックされたら編集中のファイルを上書き保存することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public partial class Form1 : Form { private void SaveFileMenuItem_Click(object sender, EventArgs e) { SaveFile(); } void SaveFile() { // filePathに格納されている文字列は // ファイルパスとして不適切な文字列かもしれないのでチェックする if(File.Exists(filePath)) { userControlImage1.Bitmap.Save(filePath); } else { SaveAsFile(); } } } |
はじめまして。
Formアプリケーションで
事前に指定しておいた2つのフォルダA,Bに、
それぞれ同じ名前のjpgファイルを格納する
ソフトを作成しました。
そのうえで、
指定したファイル名をA,B両方のフォルダから見つけ、
Aにあった画像を左側、Bにあった画像を右側に表示させ、
真ん中の上部にファイル名を記載したうえで
一枚の画像として保存できるようにしたいと思っています。
それぞれの画像はサイズも同じものである前提で、
掲載されているソフトをベースとして
Bにある画像をAの画像のすぐ右側に表示する方法と
ファイル名を追加する方法について教えていただけませんでしょうか。
これでどうでしょうか?
「事前に指定しておいた2つのフォルダ A, B」 のパスを A, B とします。また「指定したファイル名」を fileName とします。