Laden...
K
Benutzerbeschreibung

Forenbeiträge von Klaus L. Ingesamt 13 Beiträge

05.03.2008 - 11:04 Uhr

8o so viele Paramter!

[DllImport("gdi32.dll")] static extern int GetDIBits(IntPtr hdc, IntPtr hbmp, uint uStartScan, uint cScanLines, [Out] byte[] lpvBits, ref BITMAPINFO lpbmi, uint uUsage);  

Compiler Error: The type or namespace name 'BITMAPINFO' could not be found (are you missing a using directive or an assembly reference)? Wieso?
Hier steht C# signature, wieso geht der import net out of the box:
>

Und wenns bei mir mit GetDIBits klappen sollte, was muss man dann machen?

Sorry, hab mich vertippt. Du mußt natürlich SetDiBits nehmen. Mit GetDIBits kannst du den Inhalt einer Bitmap auslesen.

BITMAPINFO bzw. BITMAPINFOHEADER mußt du selbst definieren.

typedef struct tagBITMAPINFO { // bmi 

   BITMAPINFOHEADER bmiHeader; 
   RGBQUAD          bmiColors[1]; 
} BITMAPINFO; 
 
typedef struct tagBITMAPINFOHEADER{ // bmih 

   DWORD  biSize; 
   LONG   biWidth; 
   LONG   biHeight; 
   WORD   biPlanes; 
   WORD   biBitCount 
   DWORD  biCompression; 
   DWORD  biSizeImage; 
   LONG   biXPelsPerMeter; 
   LONG   biYPelsPerMeter; 
   DWORD  biClrUsed; 
   DWORD  biClrImportant; 
} BITMAPINFOHEADER; 
 

das ist aber nicht weiter wild.

Gruß,

Klaus

04.03.2008 - 18:58 Uhr

Es ist die bekannte Mandelbrot Menge, je nach Benutzerinteraktion mit der GUI wird jedesmal ein neue Mandelbrotmenge Pixel für Pixel reingezeichnet.

noch einfacher ist, als oben beschrieben, wenn du keine dynamische Veränderung brauchst
Also kommt diese Lösung bei mir nicht in Frage?

Doch durchaus. Unter dynamisch verstehe ich dass die Bitmap z.B. per Maus rotiert werden soll, also dass eine Bitmap bei einer Aktion der Maus, oder was auch immer, so schnell folgen kann, dass die Zeit für die Darstellung nicht ins Gewicht fällt. Bei nem Mandlebrotbaum ist das natürlich nicht kritisch. Da reicht es, wenn die Bitmap innerhalb 10-100ms fertig ist, dh. der Mandelbrot-Algotrithmus braucht ja eh länger als die Darstellung.

Gruß,

Klaus

04.03.2008 - 13:50 Uhr

Hört sich aber zu kompliziert an 😉

Ist es aber nicht. Es ist so einfach, wie ein 2D-Array vollzuschreiben. Mir ist gerade aufgefallen, dass es noch einfacher ist, als oben beschrieben, wenn du keine dynamische Veränderung brauchst. Du schreibst einfach ein Byte- oder Integer-Array voll und konvertiest das zu einer DIB. Letzteres ist im Grunde ein Befehl (in der API GetDiBits).

Was genau willst du den eigentlich machen? Geht es um ein Intensitätsdiagramm, also z.B. eine Temperaturverteilung?

Gruß,

Klaus

03.03.2008 - 14:17 Uhr

Ich bin nun also durch sekundenlange Warterei bestraft weil ich nun Paint verwende? ?(
Oder hab ich schon wieder was falsch gemacht?

nein, das ist nunmal so in .net.

Du kannst dir das leben aber auch leicht machen: Nimm einfach die Api-Funktion CreateDIBSection (Gdi32) und erzeug dir eine DIB in benötigter Größe. Die Funktion liefert dir eine Speicheradresse, an der sich die Bilddaten befinden. Diese Daten kannst du direkt (ohne Setpixel oder DC) setzen. Wenn es 24-Bit-Grafik sein soll, mußt du einzelne Bytes setzen, wenns 32-Bit sind, kannst du 4-Byte-Integer für die Farben verwenden (beachte, dass du Rot und Blau vertauschen mußt).

Du kannst dem Speicherbereich auch eine Array überstülpen (Zeiger auf die Daten in eine Safearry-Stuktur eintragen). Wie das prinzipiell geht, ist z.B. hier beschrieben: http://www.activevb.de/tutorials/tut_safearray/safearray.html

Wenn deine Bitmap befüllt ist, brauchst du sie nur noch irgendwie in ein Fenster oder eine Picturebox zu übertragen. Du könntest die DIB z.B. in einen DC laden und dann per Bitblt übertragen. Wahrscheinlich gibt es auch eine zulässige C#-Methode.

Dies Möglichkeit ist vermutllich von allen die schnellste, da keine Grafikmethoden benötigt werden, um Bits zu setzen und vor allem hast du eine persistente Grafik, die du nicht ständig neu zeichenen mußt. Obendrein kannst du die DIB auch mal schnell auf die HD dumpen.

Gerade in diesen Dingen sind die althergebrachten Methoden doch sehr viel einfacher und vor allem geradeaus.

Gruß,

Klaus

01.03.2008 - 11:42 Uhr

ps:Ich habe ehrlich gesagt jetzt schon Angst vor der Leistung der Anwendung, wenn ich bedenke für alle Zeichenaktionen "Invoken" zu müssen. Hilfeee

Wenn ich mich recht erinnere geht es auch in .net ohne GDI+ und große Mühen. Schau dir mal das hier
http://www.activevb.de/cgi-bin/upload/download.pl?id=3022 an. Das ist zwar VB.net, sollte aber leicht nach c# portierbar sein. Im Beispiel werden Wave-Dateien angezeigt (auch scroll und Zoom ist möglich) aber es sollte mit beliebigen Daten, auch mit dynamisch gelesenen, funktionieren.

Klaus

15.02.2008 - 13:38 Uhr

Würdest Du anstatt zu sagen, "das ist falsch" auch die richtige Antwort dazu geben?

Die richtige Antwort habe ich provoziert und das hat auch funktioniert. Eigentlich wäre es ja die Aufgabe eines Moderators gewesen, daraufhinzuweisen, dass deine Ausführungen falsch waren, insbesondere da sich ja bereits jemand für die falsche Antwort bedankt hatte. Ich habe selbst nicht vollständig geantwortet, weil meine Kommentare teilweise zensiert werden. Da ich ja nicht weiß, welchen Teil der Herr Zensor wegschneidet, schreib ich halt einfach nur wenig.

Übrigens bleibt die Bitmap auch ohne Header eine Bitmap. Es gab Zeiten da hatten Bitmaps keinen Header.

Gruß,

Klaus

14.02.2008 - 18:43 Uhr

Weil ein Bitmap vielleicht doch nicht wirklich ein Array ist 😉 Ein Bitmap ist ein Datenstrom.

Oh weh. Da hast du aber was mißverstanden, oder? Eine Bitmap ist ein feststehender Block von Daten, den man durchaus auch als Array betrachten kann.

Darin zu suchen ist teuer (zeitintensiv). Ein Array legt eine Struktur an, mit dessen Hilfe man auch per Index an die jeweiligen Stellen direkt zugreifen kann. Das geht in einem Datenstrom eben nicht.

Ebenfalls falsch.

Gruß,

Klaus

13.02.2008 - 21:30 Uhr

Hiho!

Resampeln geht, von 8Bit auf 16Bit umbügeln nicht

Was meinst du denn mit "umbügeln"?

Selbstverständlich kann man aus einer 8-Bit-Wav-Datei auch ein 16-Bit-Stück machen. Die Auflösung wird dadurch natürlich nicht besser, aber man kann eine Amplitude, die von +/-127 geht auch in 16 Bit, also von +/-32000 darstellen. Man muß die Amplitude dann halt hochrechnen, also *32000/127 und den Offeset berücksichtigen. Das Byte hat ja auch bei euch kein Vorzeichen, oder?

Gruß,

Klaus

11.02.2008 - 15:33 Uhr

d.h. ich möchte quasi von zoomstufe zu zoomstufe eine größere bitmap als grundlage haben.

Aua 😉

da das zeichnen mit drawline von 400TSD strecken doch recht lang dauert, habe ich die zoomstufen als png dateien gespeichert,

Du wirst doch wohl nicht alles zeichnen, wenn man nur einen Ausschnitt sieht, oder?

aber ab einer bildgröße von 5 000px x 4 000px dauert es einfach wahnsinnig lange.

Wundert mich nicht 😉

ich suche nun nach einer möglichkeit entweder die bilder schneller aufzurufen oder eine art und weise zu finden, wie ich schneller zeichnen kann.

Zeichne nur den sichtbaren Teil. Du hast doch Vektorgrafik, da kannst du dir doch den Bereich ausrechnen den du zeichnen mußt.

Klaus

11.02.2008 - 15:13 Uhr

Was muss ich da an Parametern setzen bzw. der Win32APi-Funktion Polygon mitgeben ?? ?(

Du mußt die Skalierung selber machen. D.h. du mußt jeden Polygonpunkt in x- und y-Richtung mit einem passenden Faktor multiplizieren und ihm ggf. auch noch einen Offset geben.

Du kannst zwar auch SetWorldTransform (API) einsetzten, aber es ist einfacher wenn man die Umrechnung selber macht. Hier findest du ein Beispiel:
http://www.activevb.de/cgi-bin/tippupload/preview.pl?id=76&sid=0
Das solltest du ohne weiteres nach C# übersetzen können. Die Skalierung machst du mit den Funktionen xxc und yyc. Im Beispiel ist zwar kein Polygon drin, aber die Methode sollte klar sein: Aus der Größe des Bildes errechnet man den Skalierungsfaktor (xfact und yFact) und wendet diesen dann auf jeden Polygonpunkt an.

Klaus

11.02.2008 - 15:02 Uhr

@klaus l: heißt das, dass die grafik (also zb. mit 2000x1500 px) auf zb. 4000x3000px "gestreckt wird" oder was passiert dabei? das problem ist nämlich, dass die grafik sehr "fein" ist und es mit strecken leider nich funktioniert, weil es dann verpixelt aussieht.

Beim Zoomen, wird natürlich gestreckt. Da führt kein Weg dran vorbei. Eine Bitmap wird dabei auf jeden Fall pixeliger, da die Bildpunkte größer werden. Ein besseres Ergebnis kannst du nur mittels Vektorgrafik erreichen, d.h. wenn der sichbare Ausschnitt in einem anderen Maßstab neu gezeichnet wird. Du mußt also erstmal erklären, in welchem Format deine Daten vorliegen.

Gruß,

Klaus

11.02.2008 - 14:17 Uhr

In der GDi32 ist SetViewportExtEx dafür vorgesehen. Das sollte auch für übergroße DCs, bzw. Bitmaps funktionieren. Ein Beispiel findest du hier:
http://www.activevb.de/tipps/vb6tipps/tipp0707.html
Muß allerdings übersetzt werden. Das sollte aber kein so großes Problem sein.

Klaus

11.02.2008 - 13:47 Uhr

Schau mal hier:
http://www.activevb.de/cgi-bin/tippupload/preview.pl?id=183&sid=0
Das ist zwar in VB6 geschrieben, aber ich weiß, dass der Autor eine Neigung zu .Net hat. Er wird dir das sicher nach VB.net übersetzen und von dort aus kannst du es vermutlich leicht nach C# portieren.

Klaus