gdi + Grafik :: DrawImage wirklich langsam ~~
Ich bin mit einem GDI+ - Grafik zu zeichnen, 4000*3000 Bild auf dem Bildschirm, aber es ist wirklich langsam. Es dauert etwa 300ms. Ich wünschte, es einfach nehmen weniger als 10ms.
Bitmap *bitmap = Bitmap::FromFile("XXXX",...);
//--------------------------------------------
//dieser Teil dauert etwa 300ms, schrecklich!
int width = bitmap->GetWidth();
int height = bitmap->GetHeight();
DrawImage(bitmap,0,0,width,height);
//------------------------------------------
Kann ich nicht verwenden CachedBitmap, weil ich zum Bearbeiten der bitmap später.
Wie kann ich es verbessern? Oder ist irgend etwas falsch?
Diese nativen GDI-Funktion zeichnet auch das Bild in den Bildschirm, und nehmen Sie nur 1 ms:
SetStretchBltMode(hDC, COLORONCOLOR);
StretchDIBits(hDC, rcDest.left, rcDest.top,
rcDest.right-rcDest.left, rcDest.bottom-rcDest.top,
0, 0, width, height,
BYTE* dib, dibinfo, DIB_RGB_COLORS, SRCCOPY);
//--------------------------------------------------------------
Wenn ich StretchDIBits, ich übergeben zu müssen, BITMAPINFO, Aber wie bekomme ich BITMAPINFO von Gdi+ - Bitmap-Objekt? Ich habe das experiment von FreeImage lib, ich nenne StretchDIBits mit FreeImageplus Objekt, es ziehen wirklich schnell. Aber jetzt brauche ich zum zeichnen von Bitmap-und schreiben Sie einen Algorithmus auf Bitmap bit-array, wie bekomme ich BITMAPINFO wenn ich eine Bitmap-Objekt? Es ist wirklich nervig -___________-|
InformationsquelleAutor der Frage user25749 | 2008-11-05
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie einen Bildschirm von 4000 x 3000 Auflösung? Wow!
Wenn nicht, sollten Sie ziehen nur den sichtbaren Teil des Bildes wäre, wäre es viel schneller...
[BEARBEITEN nach dem ersten Kommentar] Meine Bemerkung ist in der Tat ein bisschen blöd, ich nehme an der Methode DrawImage wird die Maske/überspringen Sie nicht benötigte Pixel.
Nachdem Ihre Bearbeitung (mit StretchDIBits), ich denke, eine mögliche Quelle der speed-Unterschied kommen könnte aus der Tatsache, dass StretchDIBits ist hardware-beschleunigt ("Wenn der Treiber keinen support für das JPEG-oder PNG-Datei Bild" ist ein Hinweis...), während DrawImage sein könnte (ich habe keinen Beweis dafür!) coded in C, die sich auf die Leistung der CPU statt der GPU ' s...
Wenn ich mich Recht erinnere, DIB-Bilder sind schnell (trotz "device independent"). Sehen High-Speed-Win32-Animation: "verwenden CreateDIBSection zu tun, high-speed-animation". OK, es gilt zu DIB vs. GDI, in alten Windows-version (von 1996!) aber ich denke, es ist immer noch wahr.
[EDIT] Vielleicht Bitmap::GetHBITMAP Funktion könnte Ihnen helfen, mit StretchDIBits (nicht getestet...).
InformationsquelleAutor der Antwort PhiLho
Wenn Sie mithilfe von GDI+, die Klasse TextureBrush, was Sie brauchen für den rendering-Bilder schnell. Ich habe geschrieben ein paar 2d-Spiele mit ihm, immer um die 30 FPS oder so.
Habe ich nie geschrieben .NET-code in C++, hier ist also ein C#-ish Beispiel:
InformationsquelleAutor der Antwort Cybis
Nur ein Gedanke; anstatt das abrufen der Breite und Höhe des Bildes vor dem zeichnen, warum nicht-cache-diese Werte, wenn Sie das Bild laden?
InformationsquelleAutor der Antwort Patrik Svensson
Erkunden Sie die Auswirkungen der expliziten festlegen der Interpolations-Modus zu NearestNeighbor (wobei, in deinem Beispiel sieht es aus wie die interpolation ist eigentlich nicht nötig! Aber 300ms ist die Art von Kosten zu tun hohe Qualität der interpolation, wenn keine interpolation nötig, so seine einen Versuch Wert)
Andere Sache, zu erkunden, ist das ändern der Farbtiefe der bitmap.
InformationsquelleAutor der Antwort Will
Leider, wenn ich hatte ein ähnliches problem, ich fand, dass GDI+ ist bekannt, dass Sie viel langsamer als GDI und nicht im hardware-beschleunigte, aber jetzt Microsoft verschoben haben, die auf WPF-Sie wird nicht zurück kommen, zu verbessern GDI+!
Alle die die Hersteller von Grafikkarten verschoben wurden, auf 3D-performance und scheinen nicht daran interessiert, 2D-Beschleunigung, und es gibt keine klare information, auf der die Funktionen oder hardware beschleunigt ist oder nicht. Sehr frustrierend, weil geschrieben haben eine app .NET mithilfe von GDI+, ich bin nicht sehr glücklich zu ändern um eine völlig andere Technologie, um Geschwindigkeit, die es bis zu einem angemessenen Niveau.
InformationsquelleAutor der Antwort Martin
ich glaube nicht, dass Sie dir eine ganz andere, aber da bist du eigentlich nicht benötigen, um die Größe des Bildes, versuchen Sie es mit der überlastung der DrawImagedie nicht (versuchen), um die Größe:
Wie gesagt, ich bezweifle, es wird keinen Unterschied machen, denn ich bin sicherdass DrawImage prüft die Breite und Höhe der bitmap, und wenn es keine Skalierung benötigt, ruft einfach diese überlastung. (ich hoffe, dass es nicht darum gehen, durch alle 12 Millionen Pixel darstellenden keine Arbeit).
Update: Meine Grübeleien sind falsch. ich hatte inzwischen heraus gefunden, aber Jungs Kommentar erinnert mich an meine alte Antwort: Sie wollen zu geben Sie die Ziel-Größe; auch wenn es die Quelle entspricht der Größe:
Der Grund ist, weil die dpi-Unterschiede zwischen den dpi-Wert des
bitmap
und den dpi-Wert des Ziels. GDI+ wird, führen Sie die Skalierung, um das image zu kommen die richtige "Größe" (d.h. Zoll)Was ich gelernt habe, auf meine eigenen seit Oktober letzten Jahres ist, dass Sie wirklich wollen, ziehen eine "im Cache" - version Ihrer bitmap. Es ist ein
CachedBitmap
Klasse in GDI+. Es gibt einige tricks, um es zu benutzen. Aber im Ende habe ich eine Funktion bit von (Delphi -) code, der das macht.Die Einschränkung ist, dass die
CachedBitmap
können unwirksam sein - was bedeutet, es kann nicht verwendet werden, um zu zeichnen. Dies geschieht, wenn der Benutzer änderungen, Auflösungen oder Farbtiefen (z.B. Remote Desktop). In diesem Fall wird dieDrawImage
schlägt fehl, und Sie müssen neu erstellt werden, dieCachedBitmap
:Den
cachedBitmap
übergeben nach Verweis. Der erste AufrufDrawCachedBitmap
es zwischengespeichert version erstellt werden. Sie übergeben werden, die in nachfolgenden aufrufen, z.B.:verwende ich die routine zum zeichnen der Glyphen auf Schaltflächen, unter Berücksichtigung der aktuellen DPI. Das gleiche könnte verwendet worden sein, die durch das Internet Explorer-team, um Bilder zeichnen, wenn der Benutzer läuft, auf dem hohen dpi (ie ist sehr langsam zeichnen von gezoomten Bildern, weil Sie die GDI+ verwenden).
InformationsquelleAutor der Antwort Ian Boyd
Versuchen durch kopieren der Bitmap aus Datei. FromFile Funktion auf einige Dateien gibt "slow" - Bild, aber seine Kopie zieht schneller.
InformationsquelleAutor der Antwort eugeniy
/*
Erstmal sorry für ma Deutsch, Englisch, und der code ist teilweise in Polnisch, aber es ist einfach zu verstehen.
Ich hatte das gleiche problem und ich fand die beste Lösung. Hier ist es.
Nicht mit: Graphics graphics(hdc); Grafik.DrawImage(gpBitmap, 0, 0); Es ist langsam.
Verwenden: GetHBITMAP(Gdiplus::Color(), &g_hBitmap) für HBITMAP und zeichnen mit meiner Funktion ShowBitmapStretch().
Können Sie die Größe, und es ist viel schneller! Artur Czekalski /Polen
*/
InformationsquelleAutor der Antwort Sator666
Habe ich einige gemacht, die Erforschung und war nicht in der Lage, einen Weg zu finden, um das Rendern von Bildern mit GDI/GDI+ schneller als
und gleichzeitig so einfach ist es.
Bis ich entdeckte
und ja, es ist wirklich so einfach und schnell.
InformationsquelleAutor der Antwort Mostafa Saad