2016-03-19 9 views
1

Ich verwende PictureBox-Steuerelement, um komplizierte Diagramme zu zeichnen, und um die Leistung zu optimieren, verwende ich eine Cache-Bitmap für jede Ebene der Zeichnung und zeichne sie auf das Steuerelementbild, die oberen Ebenen sind transparent Hintergründe, ich muss sie löschen und bei jeder Änderung neu zeichnen.Löschen einer Bitmap in .Net

Angenommen, g-Instanz der Graphics-Klasse der Bitmap, mit g.Clear(Color.White) zeichnet ein weißes Rechteck über alles und so unteren Schichten versteckt, und g.Clear(Color.Transparent) zeichnet Transparent Rechteck über, was bedeutet, nichts zu tun.

Gibt es keine Möglichkeit, das Bitmap zu löschen, um es in den ursprünglichen Zustand zurückzuversetzen?

+0

Wenn sie sich nicht so oft ändern, würde ich die unteren Ebenen in eine Bitmap zeichnen, die ich als PictureBox.Image oder sogar Hintergrundbild. Abgesehen davon, dass ich nicht thik bin, gibt es eine Möglichkeit, alle Bitmaps zu zeichnen, die das Gesamtbild ausmachen, wenn sich jemand ändert. Sie können jedoch nicht nur die einzelnen Layer, sondern auch deren Composites zwischenspeichern. Sie müssen jedoch immer noch alle Bitmaps aus der geänderten Ebene nach oben neu erstellen. - Btwe: Ich bin mir nicht sicher, ob Sie ein Wort gewählt haben: Es sieht so aus, als würden Sie nicht so sehr nach einem __Bitmap__ fragen, sondern nach Teilen oder all Ihren Composite-Grafiken? – TaW

+0

Wenn eine Änderung stattfindet (z. B. Bewegung), zeichne ich die Formen in der Ebene, in der sich die Änderung befindet (nachdem sie mit ihrer Hintergrundfarbe gelöscht wurde) auf das Cache-Bild ihrer Ebene und zeichne dann alle Ebenenbilder von oben nach unten auf die Bildbox .image, wenn das Bild einer Ebene mit einer anderen Farbe als "transparent" gelöscht wird, ist es in Ordnung, aber wenn die Ebene transparent ist (weil es eine Überlagerungsebene ist), wird die bewegte Form immer noch an beiden Positionen gezeichnet (alt und neu). –

+0

Lassen Sie uns das klarstellen: Sie zeichnen alle diese Schichten auf die Oberseite der einen Pb? nicht das Bild? keine verschachtelten Panles? (die sind eine nette Möglichkeit, viel von dem Neuzeichnen zu vermeiden ..) – TaW

Antwort

1

Dies ist vielleicht nicht die Antwort, die Sie gesucht haben, aber ich denke, es ist eine sehr interessante Alternative zu dem, was Sie haben.

Statt der alle Schichten von jeder Änderung nach oben zu ziehen, I Stapel so viele Schichten auf der jeweils anderen von Verschachtelung eine Anzahl von PictureBoxes in einen unteren PictureBox pBox0:

List<PictureBox> Layers = new List<PictureBox>(); 

private void Form1_Load(object sender, EventArgs e) 
{ 
    Layers.Add(pBox0); 
    setUpLayers(pBox0 , 20); // stacking 20 layers onto the botton one 
    timer1.Start();   // simulate changes 
} 

Die Stapelung ist gesetzt wie folgt auf:

void setUpLayers(Control parent, int count) 
{ 
    for (int i = 0; i < count; i++) 
    { 
     PictureBox pb = new PictureBox(); 
     pb.BorderStyle = BorderStyle.None; 
     pb.Size = parent.ClientSize; 
     Bitmap bmp = new Bitmap(pb.Size.Width,pb.Size.Height,PixelFormat.Format32bppPArgb); 
     pb.Image = bmp; 
     pb.Parent = i == 0 ? pBox0 : Layers[i - 1]; 
     Layers.Add(pb); 
    } 
} 

Für die beste Leistung I Format32bppPArgb als das Pixel-Format verwenden.

Zum Testen betreibe ich ein Tick Ereignis, das zufällig auf eine Schicht zieht:

Random R = new Random(9); 
private void timer1_Tick(object sender, EventArgs e) 
{ 
    int l = R.Next(Layers.Count-1) + 1; 

    Bitmap bmp = (Bitmap) Layers[l].Image; 
    using (Graphics G = Graphics.FromImage(Layers[l].Image)) 
    { 
     G.Clear(Color.Transparent); 
     using (Font font = new Font("Consolas", 33f)) 
     G.DrawString(l + " " + DateTime.Now.Second , font, Brushes.Gold, 
      R.Next(bmp.Size.Width), R.Next(bmp.Size.Height)); 
    } 
    Layers[l].Image = bmp; 
} 

Um alle Schichten in einem Bitmap sammeln würden Sie Verwendung des DrawToBitmap Methode machen:

Bitmap GetComposite(Control ctl) 
{ 
    Bitmap bmp = new Bitmap(ctl.ClientSize.Width, ctl.ClientSize.Height, 
          PixelFormat.Format32bppArgb); 
    ctl.DrawToBitmap(bmp, ctl.ClientRectangle); 
    return bmp; 
} 

Das Ergebnis kann dann gespeichert oder auf andere Weise verwendet werden.

Beachten Sie, dass das Erstellen zu vieler Ebenen auf diese Weise ein Limit für Fenstergriffe erreicht; Ich habe dieses Limit bei etwa 90 Layern erreicht. Wenn Sie mehr als ein paar Dutzend Schichten benötigen, wird eine komplexere Cache-Strategie benötigt.