2 Stimmen

Grafiken erstellen eines leeren Bildes - Manchmal

Ich arbeite an einer Astronomieanwendung, in der ich ein Bild im wissenschaftlichen 16-Bit-FITs-Format (monochrom) in einem PictureBox anzeigen muss. Ich greife auf eine andere DLL zu, die eine komplexe Astrometrie durchführt und auch ein skaliertes, 8-Bit-DIB-Bild des FITS-Bildes bereitstellt (ich muss diese DLL verwenden). Sie ist jedoch für VB6 geschrieben und funktioniert nicht mit einem C# VS2010 Bitmap. Der einzige Weg, wie ich dies zum Laufen gebracht habe, ist über Graphics. Die Methode "PaintPicture" ist eine externe DLL-Methode, die die Konvertierung durchführt. Das Problem bei diesem Ansatz ist, dass oft ein leeres Bild erzeugt wird, insbesondere im Debug-Modus:

obs.FITSbmp = new Bitmap(obs.p.Columns, obs.p.Rows);
pictureBoxFITS.BackgroundImage = obs.FITSbmp;
obs.g = Graphics.FromImage(obs.FITSbmp); 
//Muss über Graphics gehen, da PP auf VB6 abzielt
obs.pic.PaintPicture((int)obs.g.GetHdc());
obs.g.ReleaseHdc();

Hat jemand eine Idee, warum das passiert, und vor allem, wie man es beheben kann? Fehlt mir hier etwas oder mache ich etwas falsch?

1voto

Spektre Punkte 45051

Dies liegt weit weit entfernt von meinem Fachgebiet, aber hier sind ein paar Hinweise, die vielleicht helfen können:

  1. Es sieht so aus, als ob du (oder die DLL) GDI benutzt.

    • Stelle sicher, dass alle Aufrufe über den Hauptanwendungsthread erfolgen.
    • Wenn nicht, funktioniert GDI manchmal nicht ordnungsgemäß ...
    • Gleiches gilt für alle visuellen Elemente auf dem Desktop/im Vollbildmodus
  2. Bist du sicher, dass das unkonvertierte Bitmap richtig gerendert wird?

    • Versuche es vor der Konvertierung in eine Datei zu dumpen
    • und überprüfe es, nachdem dein Problem aufgetreten ist
    • Wenn es auch leer ist, dann
    • könnte das Problem woanders liegen

[Edit1] Direkter Bitmap-Zugriff VCL (Code in BDS2006 C++, du musst also *bmp-Sachen in VB-Stil umwandeln)

//---------------------------------------------------------------------------
void bmp_example()
    {
    Graphics::TBitmap *bmp;
    int **pyx=NULL,xs=0,ys=0;

    // [Bitmap-Initialisierung verwenden]
    bmp=new Graphics::TBitmap;  // neue VCL-Bitmape
    bmp->HandleType=bmDIB;      // ist geräteunabhängig, um direkten Zugriff zu ermöglichen
    bmp->PixelFormat=pf32bit;   // Ich verwende 32 Bit, um Pixel mit int/DWORD-Variablengröße anzupassen

    // Hier Daten in die Bitmap rendern/laden
    bmp->Width=2500;             // zum Beispiel die Bitmap auf 128x128 Pixel verkleinern
    bmp->Height=2500;

    // Erstelle alles, was für den direkten Zugriff benötigt wird
    // dies muss nach jedem Bitmap-Neuzuordnen/Neugröße erfolgen
    // Hauptgedanke ist es, Zeiger in eigenen Variablen zu speichern
    // und darauf zuzugreifen, anstatt GDI zu verwenden, um Kontrollverlangsamungen zu vermeiden
    if (pyx) delete pyx;
    xs=bmp->Width;              // xs,ys = tatsächliche Bitmapgröße
    ys=bmp->Height;
    bmp->HandleType=bmDIB;      // ist geräteunabhängig, um direkten Zugriff zu ermöglichen
    bmp->PixelFormat=pf32bit;   // Ich verwende 32 Bit, um Pixel mit int/DWORD-Variablengröße anzupassen
    pyx=new int*[ys];
    for (int y=0;yScanLine[y];

    // [Direkter Zugriff]
    int x,y,*p;
    for (y=0;y

`

  • dieses Beispiel füllt 3-mal eine 2500x2500 Pixel 32-Bit-Bitmap ~ 6MP
  • auf meinem Computer (Win7 x64 AMD 3.2GHz) beträgt die Ausführungszeit etwa 118ms (kompiliert als 32-Bit-Anwendung)
  • vermeide jegliche Verwendung der Bitmap, verwende stattdessen pyx, xs, ys
  • wenn das nicht hilft, könntest du wahrscheinlich ein Leistungsproblem in deinem Code haben
  • aber ohne es hier zu posten, ist das nur eine Vermutung
  • der beste Weg besteht darin, die Zeit deiner Verarbeitungsschritte zu messen
  • und dann wirst du sehen, wo es zu Verlangsamungen kommt
  • Ich vermute, dass es sich um eine schrecklich geschriebene Schleife im Histogramm handelt
  • vergiss nicht, die Bitmap auf das Fenster zu zeichnen, bevor du sie löschst
  • außerdem kannst du sie bei der Anwendungsinitialisierung/-beendigung zuweisen/löschen und sie die ganze Zeit im Speicher behalten
  • jede Änderung der Größe/des Formats (auch innerhalb dieser DLL-Funktionen) kann den Bitmapspeicher neu zuweisen, also muss pyx aktualisiert werden...

[Edit2] Ich habe eine weitere Idee, was falsch sein könnte.

Ich sehe, dass du auf das Paintbox-Bitmap aus deiner DLL zugreifst

  • Paintbox neigt manchmal dazu, das Bild zu aktualisieren, wenn es nicht sollte (zumindest von VCL aus)
  • dies kann dein Bild leeren (ich hatte auch schon Probleme damit)
  • normalerweise bringt ein gut platzierte Aktualisierung den Dingen wieder in Ordnung
  • oder versuch, ein separates Bitmap zu erstellen und es von der DLL aus zu rendern und dann auf die Paintbox zu zeichnen.
  • wenn es leer ist und das Bitmap nicht, dann zeichne es einfach noch einmal auf die Paintbox

`

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X