2016-11-13 25 views
0

我有一個迷你繪畫程序。我想創建一個保存按鈕,將面板細節(形狀和所有繪製的東西)保存爲二進制文件。我這樣做:如何保存我作爲二進制在面板上繪製的形狀

SaveFileDialog sfd = new SaveFileDialog(); 
BinaryFormatter bf = new BinaryFormatter(); 
var stream = new BinaryReader(File.Open(sfd.FileName,FileMode.Create)); 
bf.Serialize(stream,object); 

,但它有一個錯誤,使用對象是bf.Serialize無效。我應該怎麼做?

+0

你並不需要序列化的面板,面板是不序列化。您可以考慮以下任一選項:** 1)**您可以在位圖上繪圖,然後保存位圖,或將控件繪製到圖像並保存圖像。通過這種方式,您可以將所有形狀拼合成單個圖像,並且在加載圖像後,它們不再是可編輯的形狀。這將像油漆。 ** 2)**您可以使您的形狀可序列化,然後在文件中序列化可序列化形狀的列表。然後你可以再次反序列化它們。這樣你可以加載你的形狀並讓用戶編輯它們,例如像visio。 –

+0

如果它是一個繪圖程序,你可能只想保存繪製的圖像 – Plutonix

+0

@RezaAghaei如果我使用位圖,它會保存面板的像素? – sara

回答

3

您不需要序列化面板,面板不可序列化。您可以考慮以下任一選項:

  1. 您可以在位圖上繪圖,然後保存位圖,或者將控件繪製到圖像並保存圖像。通過這種方式,您可以將所有形狀拼合成單個圖像,並且在加載圖像後,它們不再是可編輯的形狀。這將像油漆。
  2. 您可以使您的形狀可序列化,然後在文件中序列化可序列化形狀的列表。然後你可以再次反序列化它們。通過這種方式,您可以加載形狀並讓用戶編輯它們,例如Visio。

我共享這裏兩個例子:

  • 保存圖像的例子:它簡單地保存其你塗面板上的位圖圖像文件的圖紙。

  • 序列化示例:在這個例子中,我創建了一個包含像座標和顏色一些性能有一定的序列化的形狀類,然後我創建了一個SaveLoad方法,它允許您將序列號文件的形狀,也從他們反序列化該文件並再次顯示它們。您可以簡單地擴展此示例以添加一些功能,如命中測試和移動形狀。您也可以使用一個xml序列化器而不是二進制序列化器。

保存形象的例子

爲了簡單起見,在這個例子中,我只保存面板畫在一個文件中。

如果你把畫邏輯Paint事件你的小組,那麼你可以使用DrawToBitmap你控制的圖像保存到一個文件:

private void button1_Click(object sender, EventArgs e) 
{ 
    using (var bm = new Bitmap(panel1.Width, panel1.Height)) 
    { 
     panel1.DrawToBitmap(bm, new Rectangle(0, 0, bm.Width, bm.Height)); 
     bm.Save(@"d:\panel.bmp", System.Drawing.Imaging.ImageFormat.Bmp); 
    } 
} 
private void panel1_Paint(object sender, PaintEventArgs e) 
{ 
    e.Graphics.FillRectangle(Brushes.Red, 0, 0, 100, 100); 
    e.Graphics.FillRectangle(Brushes.Blue, 50, 50, 100, 100); 
} 

系列化例

您可以創建一些可序列化的形狀,如LineShapeRectangleShape來自可序列化的Shape類。我們存儲的形狀屬性在這個類中,也這些類包含繪製邏輯:

[Serializable] 
public abstract class Shape 
{ 
    public abstract void Draw(Graphics g); 
    public override string ToString() { return GetType().Name; } 
} 

[Serializable] 
public class LineShape : Shape 
{ 
    public LineShape(){ Color = Color.Blue; Width = 2; } 
    public Point Point1 { get; set; } 
    public Point Point2 { get; set; } 
    public int Width { get; set; } 
    public Color Color { get; set; } 
    public override void Draw(Graphics g) 
    { 
     using (var pen = new Pen(Color, Width)) 
      g.DrawLine(pen, Point1, Point2); 
    } 
} 

[Serializable] 
public class RectangleShape : Shape 
{ 
    public RectangleShape() { Color = Color.Red; } 
    public Rectangle Rectangle { get; set; } 
    public Color Color { get; set; } 
    public override void Draw(Graphics g) 
    { 
     using (var brush = new SolidBrush(Color)) 
      g.FillRectangle(brush, Rectangle); 
    } 
} 

您可以創建一個ShapesList類來保存形狀和包含邏輯保存和加載形狀。也畫一個表面上的所有形狀的邏輯:

[Serializable] 
public class ShapesList : List<Shape> 
{ 
    public void Save(string file) 
    { 
     using (Stream stream = File.Open(file, FileMode.Create)) 
     { 
      BinaryFormatter bin = new BinaryFormatter(); 
      bin.Serialize(stream, this); 
     } 
    } 
    public void Load(string file) 
    { 
     using (Stream stream = File.Open(file, FileMode.Open)) 
     { 
      BinaryFormatter bin = new BinaryFormatter(); 
      var shapes = (ShapesList)bin.Deserialize(stream); 
      this.Clear(); 
      this.AddRange(shapes); 
     } 
    } 
    public void Draw(Graphics g) 
    { 
     this.ForEach(x => x.Draw(g)); 
    } 
} 

然後你可以使用這些形狀和形狀列出這樣:

ShapesList Shapes; 
private void Form3_Load(object sender, EventArgs e) 
{ 
    Shapes = new ShapesList(); 
    Shapes.Add(new RectangleShape() { Rectangle = new Rectangle(0, 0, 100, 100), 
     Color = Color.Green }); 
    Shapes.Add(new RectangleShape() { Rectangle = new Rectangle(50, 50, 100, 100), 
     Color = Color.Blue }); 
    Shapes.Add(new LineShape() { Point1 = new Point(0, 0), Point2 = new Point(150, 150), 
     Color = Color.Red }); 
    this.panel1.Invalidate(); 
} 

private void button1_Click(object sender, EventArgs e) 
{ 
    Shapes.Save(@"d:\shapes.bin"); 
    Shapes.Clear(); 
    this.panel1.Invalidate(); 
    MessageBox.Show("Shapes saved successfully."); 
    Shapes.Load(@"d:\shapes.bin"); 
    this.panel1.Invalidate(); 
    MessageBox.Show("Shapes loaded successfully."); 
} 
private void panel1_Paint(object sender, PaintEventArgs e) 
{ 
    e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; 
    Shapes.Draw(e.Graphics); 
}