自作アイコンエディタで長方形を描画するのにずいぶん苦戦してしまいましたが、ちょっとインチキくさい方法を思いついてしまいました。
32×32のビットマップを作成してそこに図形を描画。そのあとBitmap.GetPixelメソッドで各ビットのカラー情報を調べれば簡単にアイコンエディタ側にも反映させることができます。
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 |
private void Box_EndRectangle(object sender, XY e) { // startX,startY、XYオブジェクトに格納されている値が適切である場合だけ処理をする if(startX != -1 && e.X != -1) { //描画先とするImageオブジェクトを作成し、そこに長方形を描く Bitmap canvas = new Bitmap(32, 32); Graphics g = Graphics.FromImage(canvas); Point startPoint; Size size; // ドラッグ開始地点とドロップされた場所から長方形のXY座標とサイズを求める GetStartPointSize(new Point(startX, startY), new Point(e.X, e.Y), out startPoint, out size); //長方形を黒で描く g.DrawRectangle(Pens.Black, startPoint.X, startPoint.Y, size.Width, size.Height); g.Dispose(); List<XY> xys = new List<XY>(); for(int i = 0; i < 32; i++) { for(int j = 0; j < 32; j++) { Color color = canvas.GetPixel(j, i); if(color.ToArgb() != 0) xys.Add(new XY(j, i)); } } foreach(var o in xys) panels[o.X, o.Y].BackColor = CurColor; canvas.Dispose(); } } |
これでうまくいきます。長方形だけでなく円や直線、塗りつぶしもこれで対応できます。
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 |
using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; using System.IO; public partial class Form1 : Form { public Form1() { InitializeComponent(); } PanelEx[,] panels = new PanelEx[32,32]; // 最初に色を表示するためのパネルを生成する private void Form1_Load(object sender, EventArgs e) { for(int row = 0; row < 32; row++) { for(int column = 0; column < 32; column++) { var box = CreateColorPanel(column, row); panels[column, row] = box; } } CurColor = Color.Black; } // 色を表示するためのパネルの生成 PanelEx CreateColorPanel(int i, int j) { int size = 14; PanelEx box = new PanelEx(i, j); box.Size = new Size(size, size); box.Location = new Point(size * i, size * j); box.Parent = panel1; box.BorderStyle = BorderStyle.FixedSingle; box.BeginRectangle += Box_BeginRectangle; box.EndRectangle += Box_EndRectangle; box.BeginLine += Box_BeginLine; box.EndLine += Box_EndLine; box.BeginEllipse += Box_BeginEllipse; box.EndEllipse += Box_EndEllipse; return box; } } |
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 { // 色の設定 Color curColor = new Color(); public Color CurColor { get { return curColor; } set { curColor = value; pictureBox1.BackColor = value; } } private void buttonColor_Click(object sender, EventArgs e) { if(colorDialog1.ShowDialog() == DialogResult.OK) CurColor = colorDialog1.Color; } } |
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 { // 描画するのは直線か長方形か楕円か? public CheckedRadioButton GetCheckedRadioButton() { if(radioButtonFree.Checked) return CheckedRadioButton.Free; else if(radioButtonRectangle.Checked) return CheckedRadioButton.Rectangle; else if(radioButtonLine.Checked) return CheckedRadioButton.Line; else if(radioButtonEllipse.Checked) return CheckedRadioButton.Ellipse; else return CheckedRadioButton.Free; } public enum CheckedRadioButton { Free = 0, Rectangle = 1, Line =2, Ellipse = 3, } } |
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 |
public partial class Form1 : Form { // ドラッグ開始地点とドロップされた場所から長方形のXY座標とサイズを求める void GetStartPointSize(Point dragPoint, Point dropPoint, out Point startPoint, out Size size) { int x = 0, y = 0, width = 0, height = 0; if(dragPoint.X <= dropPoint.X && dragPoint.Y <= dropPoint.Y) { x = dragPoint.X; y = dragPoint.Y; width = dropPoint.X - dragPoint.X; height = dropPoint.Y - dragPoint.Y; } if(dropPoint.X < dragPoint.X && dragPoint.Y <= dropPoint.Y) { x = dropPoint.X; y = dragPoint.Y; width = dragPoint.X - dropPoint.X; height = dropPoint.Y - dragPoint.Y; } if(dragPoint.X <= dropPoint.X && dropPoint.Y < dragPoint.Y) { x = dragPoint.X; y = dropPoint.Y; width = dropPoint.X - dragPoint.X; height = dragPoint.Y - dropPoint.Y; } if(dropPoint.X < dragPoint.X && dropPoint.Y < dragPoint.Y) { x = dropPoint.X; y = dropPoint.Y; width = dragPoint.X - dropPoint.X; height = dragPoint.Y - dropPoint.Y; } startPoint = new Point(x, y); size = new Size(width, height); } } |
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 Form1 : Form { // 四角形を描画する int startX = -1, startY = -1; private void Box_BeginRectangle(object sender, XY e) { startX = e.X; startY = e.Y; } private void Box_EndRectangle(object sender, XY e) { // startX,startY、XYオブジェクトに格納されている値が適切である場合だけ処理をする if(startX != -1 && e.X != -1) { //描画先とするImageオブジェクトを作成し、そこに長方形を描く Bitmap canvas = new Bitmap(32, 32); Graphics g = Graphics.FromImage(canvas); Point startPoint; Size size; GetStartPointSize(new Point(startX, startY), new Point(e.X, e.Y), out startPoint, out size); //長方形を黒で描く if(checkBoxFillsColor.Checked) { g.DrawRectangle(Pens.Black, startPoint.X, startPoint.Y, size.Width, size.Height); g.FillRectangle(Brushes.Black, startPoint.X, startPoint.Y, size.Width, size.Height); } else g.DrawRectangle(Pens.Black, startPoint.X, startPoint.Y, size.Width, size.Height); g.Dispose(); List<XY> xys = new List<XY>(); for(int i = 0; i < 32; i++) { for(int j = 0; j < 32; j++) { Color color = canvas.GetPixel(j, i); if(color.ToArgb() != 0) xys.Add(new XY(j, i)); } } foreach(var o in xys) panels[o.X, o.Y].BackColor = CurColor; canvas.Dispose(); } // 処理が終わったらstartX,startYに不適切な値をセットする。 startX = -1; startY = -1; } } |
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 |
public partial class Form1 : Form { // 直線を描画する private void Box_BeginLine(object sender, XY e) { startX = e.X; startY = e.Y; } private void Box_EndLine(object sender, XY e) { // startX,startY、XYオブジェクトに格納されている値が適切である場合だけ処理をする if(startX != -1 && e.X != -1) { //描画先とするImageオブジェクトを作成し、そこに直線を描く Bitmap canvas = new Bitmap(32, 32); Graphics g = Graphics.FromImage(canvas); g.DrawLine(Pens.Black, startX, startY, e.X, e.Y); g.Dispose(); List<XY> xys = new List<XY>(); for(int i = 0; i < 32; i++) { for(int j = 0; j < 32; j++) { Color color = canvas.GetPixel(j, i); if(color.ToArgb() != 0) xys.Add(new XY(j, i)); } } foreach(var o in xys) panels[o.X, o.Y].BackColor = CurColor; canvas.Dispose(); } // 処理が終わったらstartX,startYに不適切な値をセットする。 startX = -1; startY = -1; } } |
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 |
public partial class Form1 : Form { // 楕円を描画する private void Box_BeginEllipse(object sender, XY e) { startX = e.X; startY = e.Y; } private void Box_EndEllipse(object sender, XY e) { // startX,startY、XYオブジェクトに格納されている値が適切である場合だけ処理をする if(startX != -1 && e.X != -1) { //描画先とするImageオブジェクトを作成し、そこに楕円を描く Bitmap canvas = new Bitmap(32, 32); Graphics g = Graphics.FromImage(canvas); Point startPoint; Size size; GetStartPointSize(new Point(startX, startY), new Point(e.X, e.Y), out startPoint, out size); //楕円を黒で描く if(checkBoxFillsColor.Checked) { g.FillEllipse(Brushes.Black, startPoint.X, startPoint.Y, size.Width, size.Height); g.DrawEllipse(Pens.Black, startPoint.X, startPoint.Y, size.Width, size.Height); } else g.DrawEllipse(Pens.Black, startPoint.X, startPoint.Y, size.Width, size.Height); g.Dispose(); List<XY> xys = new List<XY>(); for(int i = 0; i < 32; i++) { for(int j = 0; j < 32; j++) { Color color = canvas.GetPixel(j, i); if(color.ToArgb() != 0) xys.Add(new XY(j, i)); } } foreach(var o in xys) panels[o.X, o.Y].BackColor = CurColor; canvas.Dispose(); } // 処理が終わったらstartX,startYに不適切な値をセットする。 startX = -1; startY = -1; } } |
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 |
public partial class Form1 : Form { // 文字を描画する // フォントを設定する FontDialog FontDialog = new FontDialog(); Font CurFont = new Font("MS 明朝", 20); private void buttonFont_Click(object sender, EventArgs e) { FontDialog.Font = CurFont; if(FontDialog.ShowDialog() == DialogResult.OK) { CurFont = FontDialog.Font; } } // 文字を描画する private void buttonInsertString_Click(object sender, EventArgs e) { string str = textBox1.Text; if(str == "") { MessageBox.Show("文字が入力されていません", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } Bitmap canvas = new Bitmap(32, 32); Graphics g = Graphics.FromImage(canvas); g.DrawString(str, CurFont, Brushes.Black, new PointF(0F, 0F)); g.Dispose(); List<XY> xys = new List<XY>(); for(int i = 0; i < 32; i++) { for(int j = 0; j < 32; j++) { Color color = canvas.GetPixel(j, i); if(color.ToArgb() != 0) xys.Add(new XY(j, i)); } } foreach(var o in xys) panels[o.X, o.Y].BackColor = CurColor; canvas.Dispose(); } } |
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 |
public partial class Form1 : Form { // 作成したアイコンをファイルとして保存する private void buttonSaveIcon_Click(object sender, EventArgs e) { // まずビットマップを取得する Bitmap bmp = new Bitmap(32, 32); for(int row = 0; row < 32; row++) { for(int column = 0; column < 32; column++) { bmp.SetPixel(column, row, panels[column, row].BackColor); } } SaveFileDialog dlg = new SaveFileDialog(); dlg.Filter = "アイコン| *.ico"; if(dlg.ShowDialog() != DialogResult.OK) return; //ビットマップをアイコンへ変換 Icon icon = Icon.FromHandle(bmp.GetHicon()); Stream outStream = new FileStream(dlg.FileName, FileMode.Create, FileAccess.Write); icon.Save(outStream); outStream.Dispose(); bmp.Dispose(); icon.Dispose(); } } |
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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
public class PanelEx : Panel { int Column = 0; int Row = 0; public delegate void XYHandler(object sender, XY e); public event XYHandler BeginRectangle; public event XYHandler EndRectangle; public event XYHandler BeginLine; public event XYHandler EndLine; public event XYHandler BeginEllipse; public event XYHandler EndEllipse; public PanelEx(int column, int row) { Column = column; Row = row; this.MouseDown += PanelEx_MouseDown; this.DragOver += PanelEx_DragOver; this.DragDrop += PanelEx_DragDrop; this.GiveFeedback += PanelEx_GiveFeedback; this.AllowDrop = true; } private void PanelEx_MouseDown(object sender, MouseEventArgs e) { Form1 f = (Form1)FindForm(); this.BackColor = f.CurColor; if(f.GetCheckedRadioButton() == Form1.CheckedRadioButton.Free) { DoDragDrop(0, DragDropEffects.All); } if(f.GetCheckedRadioButton() == Form1.CheckedRadioButton.Rectangle) { BeginRectangle?.Invoke(this, new XY(Column, Row)); DoDragDrop(0, DragDropEffects.All); EndRectangle?.Invoke(this, new XY(-1, -1)); } if(f.GetCheckedRadioButton() == Form1.CheckedRadioButton.Line) { BeginLine?.Invoke(this, new XY(Column, Row)); DoDragDrop(0, DragDropEffects.All); EndLine?.Invoke(this, new XY(-1, -1)); } if(f.GetCheckedRadioButton() == Form1.CheckedRadioButton.Ellipse) { BeginEllipse?.Invoke(this, new XY(Column, Row)); DoDragDrop(0, DragDropEffects.All); EndEllipse?.Invoke(this, new XY(-1, -1)); } } private void PanelEx_DragOver(object sender, DragEventArgs e) { e.Effect = DragDropEffects.All; Form1 f = (Form1)FindForm(); if(f.GetCheckedRadioButton() == Form1.CheckedRadioButton.Free) { this.BackColor = f.CurColor; } } private void PanelEx_DragDrop(object sender, DragEventArgs e) { Form1 f = (Form1)FindForm(); if(f.GetCheckedRadioButton() == Form1.CheckedRadioButton.Rectangle) { EndRectangle?.Invoke(this, new XY(Column, Row)); } if(f.GetCheckedRadioButton() == Form1.CheckedRadioButton.Line) { EndLine?.Invoke(this, new XY(Column, Row)); } if(f.GetCheckedRadioButton() == Form1.CheckedRadioButton.Ellipse) { EndEllipse?.Invoke(this, new XY(Column, Row)); } } private void PanelEx_GiveFeedback(object sender, GiveFeedbackEventArgs e) { e.UseDefaultCursors = false; Cursor = Cursors.Arrow; } } |
1 2 3 4 5 6 7 8 9 10 |
public class XY { public XY(int x, int y) { X = x; Y = y; } public int X = 0; public int Y = 0; } |