Bild aus DC abspeichern, wie?

Hallo
Habe VB5, mein Problem:
Ich erzeuge eine Bitmap mit API-Funktionsaufrufen unter Verwendung eines Datenfeldes für die Pixeldaten.
Ich kopiere nun mit Bitblt dieses Bild aus einem kompatiblen DC in einen zum Beispiel Picture2.HDC .
Funktioniert auch, Bild ist in der PictureBox.
Aber das Bild ist in der Picturebox nicht beständig, VB weiß nichts vom Bild im Windows-DC und es geht auch verloren, wenn ich das Bild kurz über den Monitorrand schiebe.
Basic Methoden wie „Refresh“ oder „Autoredraw“ funktionieren nicht und löschen das Bild.
Um nun dieses Bild beständig zu machen, habe ich eine Methode gefunden:
Ich stelle Punkt für Punkt mit API fest, welche Farbe eben da ist, und punkte in das Bild zurück mit dem Basic „Punkter“. Dauert aber lange.
Es könnte auch über das Screen-Objekt und dem Basic gehen, weiß ich jetzt nicht genau.

Aber ich möchte lieber aus dem DC ins Basic kopieren, so das es auch funktioniert, wenn Stellen nicht sichtbar sind.
Ich finde im MSDN und im Internet keine Lösung.
Es steht zwischendurch unter anderem auch ein Handle für eine DIB-Bitmap zur Verfügung.

Vielen Dank für einen guten Tip.
MfG
Matthias

Hallo Matthias,

Habe VB5, mein Problem:
Ich erzeuge eine Bitmap mit API-Funktionsaufrufen unter
Verwendung eines Datenfeldes für die Pixeldaten.
Ich kopiere nun mit Bitblt dieses Bild aus einem kompatiblen
DC in einen zum Beispiel Picture2.HDC .
Funktioniert auch,

bis hier her keine Ahnung, wovon Du redest. :wink:

Bild ist in der PictureBox.

Ab hier ja.

Aber das Bild ist in der Picturebox nicht beständig, VB weiß
nichts vom Bild im Windows-DC und es geht auch verloren, wenn
ich das Bild kurz über den Monitorrand schiebe.
Basic Methoden wie „Refresh“ oder „Autoredraw“ funktionieren
nicht und löschen das Bild.

Autoredraw muß gehen. Setze Autoredraw mal vor der Bearbeitung auf true.
Noch etwas zum besseren Verständnis, wird sicher helfen.
Das Picturesteuerelement unterscheidet zwischen den geladenen Daten ( .Picture) und dem angezeigten Bild ( .Image).
Im Zweifel gaht immer noch …

Picture1.Picture = Picture1.Image 
Picture1,Refresh

Aber ich möchte lieber aus dem DC

??? verstehe ich nicht. Was heißt DC? Eventuell kann ich mehr helfen, wenn Du die Abkürzung erklärst.

ins Basic kopieren, so das
es auch funktioniert, wenn Stellen nicht sichtbar sind.

Gruß, Rainer

Hallo Matthias,

Hallo Rainer, erstmal danke für die Antwort, aber ich fürchte, sie trifft nicht meine Frage. Um auf Deine Antwort einzugehen:

Habe VB5, mein Problem:
Ich erzeuge eine Bitmap mit API-Funktionsaufrufen unter
Verwendung eines Datenfeldes für die Pixeldaten.
Ich kopiere nun mit Bitblt dieses Bild aus einem kompatiblen
DC in einen zum Beispiel Picture2.HDC .
Funktioniert auch,

bis hier her keine Ahnung, wovon Du redest. :wink:

Die angewendeten Windows-Api Funktionen lauten:
CreateDibSection, um aus einem Datenfeld eine Bitmap zu erzeugen.
CreateCompatibleDc
SelectObject
BitBlt
DeleteObject usw…
Die DibSection ist eine Bitmap im Dib-Format. Sie hat den Vorteil, das unabhängig von den Monitoreinstellungen das Bild dargestellt werden kann.

Ein DC ist ein DeviceContext, entsprechend der HDc Eigenschaft unter VB. Ein DC ist das Treiberobjekt oder Gerät unter Windows.
VB kopiert seine Bilder in dieses Objekt.

Aber das Bild ist in der Picturebox nicht beständig, VB weiß
nichts vom Bild im Windows-DC und es geht auch verloren, wenn
ich das Bild kurz über den Monitorrand schiebe.
Basic Methoden wie „Refresh“ oder „Autoredraw“ funktionieren
nicht und löschen das Bild.

Autoredraw muß gehen. Setze Autoredraw mal vor der Bearbeitung
auf true.
Noch etwas zum besseren Verständnis, wird sicher helfen.
Das Picturesteuerelement unterscheidet zwischen den geladenen
Daten ( .Picture) und dem angezeigten Bild ( .Image).
Im Zweifel gaht immer noch …

Picture1.Picture = Picture1.Image
Picture1,Refresh

Nein, schon probiert, aber ich probiere es noch einmal, für den Fall, das ich einen Fehler drin haben sollte.

Ich habe auch schon die vorherigen Artikel gelesen, wo dasselbe schon mal drinstand, es betrifft aber irgendwie nicht mein Problem.
Wenn gar nichts anderes geht, muß ich eine Datei zusammenbasteln, welche dem *.bmp Dateiformat entspricht, diese abspeichern und dann wieder laden. Selbiges wollte ich aber vermeiden.
MfG
Matthias

Hallo Matthias,

Die angewendeten Windows-Api Funktionen lauten:
CreateDibSection, um aus einem Datenfeld eine Bitmap zu
erzeugen.
CreateCompatibleDc
SelectObject
BitBlt
DeleteObject usw…
Die DibSection ist eine Bitmap im Dib-Format. Sie hat den
Vorteil, das unabhängig von den Monitoreinstellungen das Bild
dargestellt werden kann.

OK, das habe ich jetzt zum Teil verstanden. Du arbeitest da mit einer API die ich mir noch nie angesehen habe.

Ich habe auch schon die vorherigen Artikel gelesen, wo
dasselbe schon mal drinstand, es betrifft aber irgendwie nicht
mein Problem.

Ja, das war etwas völlig anderes.

Wenn gar nichts anderes geht, muß ich eine Datei
zusammenbasteln, welche dem *.bmp Dateiformat entspricht,
diese abspeichern und dann wieder laden. Selbiges wollte ich
aber vermeiden.

Kann ich gut verstehen. :wink:

Zurück nach oben. … Du hast ein Objekt, das Deine Grafik enthält. Richtig?
Daß ich nicht vertanden habe, in welchem Format die Grafik vorliegt habe ich schon bemerkt. Kannst Du die an das Clipboard übergeben? …

Es sieht zwar so aus, als könnte ich dir nicht helfen, aber kannst du mir mal ein rudimentäres Projekt mit dieser Funktion mailen? Würde ich mir gern mal ansehen. Ob Dir das am Ende hilft, kann ich nicht sagen, sieht aber eher nicht so aus. :wink:

Gruß, Rainer

Hallo Matthias,

also du sagst das das Bild schon in einer Picturebox ist, aber in gewissen Situationen verloren geht?
hmm, an deiner stelle würde ich einfach über Savepicture das Bild temp. abspeichern und danach wieder laden. So sollte es dann passen.
Es ist nicht die feine englische Art aber ne Lösung :smile:
Ansonsten, probiere doch mal folgendes.

Durchlaufe das Bild, ermittle punkt für punkt mit getpixel. Den hdc für das bild hast du ja. Setze danach den Punkt mittels setpixel neu
Am ende machst du die zuweisung wie rainer beschrieben hat.

picture2.picture = picture2.image
picture2.refresh

Setze aber zum anfang autoredraw auf true!

Dann sollte es gehen. Ich selbst hatte letztens ähnliche probs gehabt :smile:

MFG Alex

Zurück nach oben. … Du hast ein Objekt, das Deine Grafik
enthält. Richtig?
Daß ich nicht vertanden habe, in welchem Format die Grafik
vorliegt habe ich schon bemerkt. Kannst Du die an das
Clipboard übergeben? …

Hallo Rainer
Im VB habe ich kein Objekt, welches ein Bild darstellt, lediglich die Image-Eigenschaft war schon mal nicht Null, konnte ich aber nicht übergeben.
Das mit dem Clipboard könnte ich mal ausprobieren, mal sehen, ob die Picturebox ein Ctrl-C akzeptiert. Ich bin da aber nicht so für, weil das Cipboard dabei geleert wird.
Das Programm selber hab ich auf einem anderen Computer, ich müßte Ihn erst hier anschließen.
Ich habe aber trotzdem schon alles genau erklärt.
In einfachen Worten: Mit den Windows-Api Funktionen kriege ich bisher keine beständige Bitmap ins VB-Picture-Control.

MfG
Matthias

Hallo Alex

hmm, an deiner stelle würde ich einfach über Savepicture das
Bild temp. abspeichern und danach wieder laden. So sollte es
dann passen.

Savepicture wird nicht gehen, weil das Bild noch nicht im VB erscheint. Es ist lediglich im Windows-Device-Kontext. Aber ich werde es auch mal ausprobieren.

Durchlaufe das Bild, ermittle punkt für punkt mit getpixel.
Den hdc für das bild hast du ja. Setze danach den Punkt
mittels setpixel neu

Das funktioniert bereits, wenn ich statt SetPixel die VB-Funktion zum Punkten nehme. Dauert mir aber zu lange. Bei einem 2.6GHz Computer und kleinem Bild etwa 10 sec. Außerdem sind nicht immer alle Pixel sichtbar, wenn zum Beispiel gerade ein anderes Window drüberkommt.

Am ende machst du die zuweisung wie rainer beschrieben hat.

picture2.picture = picture2.image
picture2.refresh

Setze aber zum anfang autoredraw auf true!

Das funktioniert leider bei mir überhaupt nicht, habe ich auch schon geschrieben. Da ist eventuell auch ein Unterschied in den VB-Versionen.
MfG

Hallo Matthias,

Da ist eventuell auch ein Unterschied in
den VB-Versionen.

Ich habe VB4.0 und VB6.0, da ist es gleich. Deshalb vermute ich, daß 5.0 da nicht derart aus der Reihe tanzt.

Gruß, Rainer

Hallo Rainer,

ich hab die 5.0 und die 6.0 jeweils die Enterprice Edition und was in VB 5 geht klappt anstandslos in VB 6.

MFG Alex

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hallo Matthias,

Das mit dem Clipboard könnte ich mal ausprobieren, mal sehen,
ob die Picturebox ein Ctrl-C akzeptiert.

Wieso das? Picture1.Picture = Clipboard.Getdata wäre da richtig. :wink:

Ich bin da aber nicht
so für, weil das Cipboard dabei geleert wird.

Muß ja auch nicht so bleiben. Wenn’s aber geht, bist Du der Lösung schon mal nahe.

Gruß, Rainer

Gruß, Rainer

Hallo Rainer

Endlich hab ichs raus…
Ich dachte zuerst, Ihr wollt mich verarsc… aber dann habe ich auf einer Internetseite vom selben Problem gelesen…

Ich muß bei vb5 diese Reihenfolge einhalten:

Picture2.Autoredraw = True
API-Methoden
Picture2.Refresh

das ist schon alles, damit die Bitmap bleibt. Endlich und Hurra
MfG