Frage

C ++ und .net Ich habe einen Strom von Daten, die ich als Scrolling Bild angezeigt werden soll. Jedes Mal, wenn ich ein paar neue Daten bekomme ich es als eine neue Zeile (128x1 Pixel) und blättern Sie den vorherigen Inhalt zu einer Seite hinzufügen möchte.

Mein erster Stich an dem Problem beteiligt die gesamten Daten-Rendering jedes Mal stelle ich eine neue Reihe bekam. Das funktionierte, war aber viel zu langsam, so dass ich denke, es könnte mehr Sinn, einen Puffer von einer Art zu schreiben machen (eine Bitmap vielleicht?). Das Problem ist, dass ich kann nicht sehen, wie ich das tun kann; Graphic Objekte können Sie ganz glücklich ziehen, aber ich kann nicht eine offensichtliche Art und Weise sieht meiner Kontrolle zu sagen, ein Bitmap Objekt zu verwenden, wie es Puffer ist? In ähnlicher Weise kann ich eine Art und Weise nicht auf einer Bitmap zu zeichnen, die ich dann auf den Bildschirm schreiben.

Dies muss möglich sein, aber mein Google-foo hat mir bisher versagt ...

[Edit1] Nur um zu klären, sind die Daten ein Spektrogramm. Das folgende Bild zeigt das, was ich versuche, zu erreichen:

alt text http: //www.geekops.co.uk/photos/0000-00-02%20(Forum%20images)/ScrollingGraphicsAlgorithmExplanation.png

Die Daten, die ich bin Plotten kommt in Arrays von Schwimmern. Es gibt nichts zu begrenzen, wie viele ich werde, so möchte ich nur Daten vergessen, wie es die Seite des Grundstücks abfällt.

Ich bin vererben derzeit von einem System::Windows::Forms::UserControl , aber auf etwas anderes wechseln könnte, wenn es eine bessere alternative?

War es hilfreich?

Lösung

Werfen Sie einen Blick auf die Scroll win32 Methode. Sie können die vorhandenen Daten auf dem Bildschirm bewegen und dann nur die neuen Daten ziehen. Dies ist sehr schnell.

Andere Tipps

Bitmap bmpImage = new Bitmap (512.512);

for (int iRow = 0; iRow <512; iRow ++)

{

  for (int iCol = 0; iCol <512; iCol++)
                        {
                            Color clr;
                            bmpImage.SetPixel(iCol, iRow, clr);
                        }

}

(Image) bmpImage.save ()

Eine mögliche Strategie:

  • Zeichnen auf einem Backbuffer von links nach rechts, die um Wraps, wenn das Ende erreicht. Führt Logik nur Scrollen, wenn (mit einer spezifizierten Framerate) zu screenen, zu malen. Verwenden Sie DrawImage mit Quellrechteck und Zielrechteck dies zu erreichen.

  • Mit bitmap.LockBits (...) und bitmap.UnlockBits (...) Methode der rohen Bitmap-Daten zu ändern. Achten Sie darauf, nur das Rechteck sperren Sie ändern wollen, da eigentlich diese Funktionen Kopien der Bitmap-Daten aus dem nicht verwalteten macht verwalteten Speicher. Ein Beispiel dafür, wie dies zu tun, ist hier beschrieben Bitmap .. ::. LockBits Methode (Rechteck, ImageLockMode, Pixelformat) .

  • Eine Alternative zu LockBits ist SetPixel auf dem Bitmap zu verwenden. Aber SetPixel ist bekannt, langsam zu sein.

  • Wenn Blitten Bilder auf dem Bildschirm stellen Sie sicher, dass CompositingMode auf Graphics-Instanz bmpg.CompositingMode = CompositingMode.SourceCopy gesetzt ist, und das Pixelformat des Puffers zurück ist PixelFormat.Format32bppPArgb.

Ich bin mir nicht ganz klar, auf genau das, was Sie versuchen, (auf einem Dialog eine Art von Kontrolle?) Zu ziehen, aber einem erraten, sollte es so etwas wie arbeiten:

class Foo {
    ...
    Gdiplus::Bitmap* m_pBitmap;
};

void Foo::DrawItem(LPDRAWITEMSTRUCT lpDraw) {

   // update bitmap if needed
   if(some_condition_requiring_bitmap_redraw) {

       // do expensive drawing into bitmap
       Gdiplus::Graphics graphics(m_pBitmap);
   }


   // create a graphics object to draw the control from the bitmap
   Gdiplus::Graphics graphics(lpDraw->hDC);
   graphics.DrawImage(m_pBitmap, ...);
}

Das ist eine sehr grobe Schätzung auf es trotzdem. Der DrawItem Anruf könnte ganz anders aussehen, wenn Sie .NET verwenden (ich nicht mit ihm vertraut bin ...), aber die grundlegende Logik soll in etwa gleich sein.

Je nachdem, was genau Ihre Daten ist, kann es nicht effizient sein 1 Pixelzeilen zu einer Zeit, zu zeichnen. Sie können besser zeichnet eine große Fläche und nur Bits davon als erforderlich ist -. Obwohl das offensichtlich auf abhängen, wie Ihre Daten kommen in

Sie können auch eine Art von Update auf die Bitmap zu tun „scrollen“ seinen Inhalt. Ich werde das für Sie überlassen: -)

Versuchen Sie Folgendes:

  • Starten Sie eine neue VC ++ WinForms-Anwendung.
  • Fügen Sie einen Benutzer Steuerelement mit dem Namen ‚Spektrogramm‘ zu dem Projekt
  • Fügen Sie ein Timer-Steuerelement auf die Benutzersteuerung ‚Spektrogramm‘ und stellen Sie die ‚Aktiviert‘ Eigenschaft auf true
  • Fügen Sie die folgenden privaten Variablen auf die Benutzerkontrolle ‚Spektrogramm‘
private:
Graphics ^m_gfxBuffer;
Graphics ^m_gfxOriginal;
Bitmap ^m_bmpBuffer;
Bitmap ^m_bmpOriginal;
  • Fügen Sie den folgenden Code in das 'Spektrogramm' Konstruktor:

m_bmpBuffer = gcnew Bitmap(this->ClientSize.Width, this->ClientSize.Height);
m_gfxBuffer = Graphics::FromImage(m_bmpBuffer);
m_bmpOriginal = gcnew Bitmap(this->ClientSize.Width, this->ClientSize.Height);
m_gfxOriginal = Graphics::FromImage(m_bmpOriginal);
this->SetStyle(::ControlStyles::AllPaintingInWmPaint | ::ControlStyles::DoubleBuffer | ::ControlStyles::UserPaint | ::ControlStyles::OptimizedDoubleBuffer, true);
this->UpdateStyles();
  • Fügen Sie den folgenden Code in das Paint-Ereignis 'Spektrogramm':

array<unsigned char, 1> ^bytes = gcnew array<unsigned char, 1>(m_bmpBuffer->Height * 3);
Random ^r = gcnew Random();
r->NextBytes(bytes);

m_gfxOriginal->DrawImage(m_bmpBuffer, -1, 0);

int y = 0;
for (int i = 0; i < m_bmpOriginal->Height * 3; i += 3)
{
  m_bmpOriginal->SetPixel(m_bmpOriginal->Width - 1, y++, ::Drawing::Color::FromArgb(255, bytes[i], bytes[i + 1], bytes[i + 2]));
}

m_gfxBuffer->DrawImage(m_bmpOriginal, 0, 0);
e->Graphics->DrawImage(m_bmpOriginal, 0, 0);    
  • Fügen Sie den folgenden Code der 'Spektrogramm' Timer Event ankreuzen

this->Invalidate(false);
  • Speichern Sie Ihr Projekt
  • Reinigen und Wiederaufbau
  • Führen Sie das Projekt
  • Schließen Sie die Lauftechnik
  • Die Steuerung Spektrogramm Benutzer soll jetzt in der 'Toolbox' sein
  • Ziehen Sie es von der ‚Toolbox‘ auf das Formular und Sie sollten ein Scrolling-zufälliges farbiges Spektrogramm von Arten sehen.

Das sollten Sie eine allgemeine Vorstellung von einer Bitmap-gepufferte Kontrolle. Der Schlüssel hier ist der „SetStyle“ Aufruf im Konstruktor und der Versatz der Bitmap von -1 in dem Paint-Ereignisse.

Sie müssen angemessen über die Grafiken verfügen und Bitmap-Objekte sowie Griff zu zerstören und sie in dem Resize-Ereignisse neu zu erstellen.

Hoffe, das hilft. Lassen Sie mich wissen, wie es geht.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top