"Sreenshot" von PictureBox

  • VB.NET

Es gibt 22 Antworten in diesem Thema. Der letzte Beitrag () ist von ~blaze~.

    "Sreenshot" von PictureBox

    Hi, ich habe eine PictureBox in die ich mit recht viel Aufwand und in mehreren Schritten Gradienten, Linien und Text plotten lasse. Jetzt will ich diese auch ausdrucken lassen. Mein Gedanke war, dass man vielleicht so eine Art Screenshot von der PictureBox nehmen und diesen als BMP Spreichern kann. Dies ist aber nur bildlich zu verstehen, wenn letztendlich möchte ich den Inhalt auch speichern ohne, er umbedingt angezeigt werden soll. Habt Ihr vielleicht ein paar Inputs, wie man das realisiern könnte?

    Danke!

    Gruß, Tobias
    Hi
    zu 1.: mit dem Sub DrawToBitmap kannst du die PictureBox in ein Bitmap-Objekt zeichen lassen.

    VB.NET-Quellcode

    1. Dim bmp As New Bitmap(Picturebox1.Width, PictureBox1.height)
    2. PictureBox1.DrawToBitmap(bmp,New Rectangle(0,0,PictureBox1.Width,PictureBox1.height))

    zu 2.: du kannst direkt auf die Bitmap zeichnen:

    VB.NET-Quellcode

    1. Dim bmp As new bitmap(100,100)
    2. Dim Graph As graphics = graphics.fromimage(bmp)
    3. With Graph
    4. 'dein zeichencode
    5. End With
    6. Graph.Dispose()
    7. bmp.Save("Pfad", Format)


    Gruß
    ~blaze~
    Hey, danke ihr beiden. Das klappt wunderbar. Jetzt habe ich nur noch ein kleines Problem...

    Ich möchte die Bitmap nicht auf der Platte ablegen sondern nur zwischenspeichern, um sie später in einem PrintDocument einzufügen. Dazu komm noch, dass ich nicht nur eine dieser PictureBox Abbilder generiere sondern gleich vier! Die Zwischenablage fällt hierfür ja wohl aus... Kennt Ihr da eine Möglichkeit, wie man das bewerkstelligen kann?


    Also ich würde gerne die erstellten Bitmaps überall im Programm verfügbar machen. Sozusagen Public...
    Oder kann ich evtl. das Bild in My.Resources speichern. Und wenn ja, wie geht das?

    Vielen Dank!

    Gruß, Tobias

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Panavia“ ()

    Ich vermute dein Programm besteht aus mehreren Formen (z.B. als MDI).
    Der Picturebox werden auf einer dieser Form Werte zugeordnet sie soll aber auch noch auf einer anderen
    zugreifbar sein.
    Ich würde die Variablen für die Picturebox einfach in einem Modul speichern, dann kannst du sie auf allen Formen abrufen.
    Projekt->Windows Form hinzu->Modul
    Wie schon erwähnt wurde, ist Modul eine eher veraltete Sache (ich habe da einen riesig über den Deckel gezogen gekriegt!) Also würde ich es eher im Ram selbst speichern, oder per Clipboard. Eine Public Variable wäre eher meine letze Lösung, die ich machen würde!
    Hey danke, ich bekomme es aber nicht hin. ich möchte "einfach" aus dem Beispiel von ~blaze~:
    zu 1.: mit dem Sub DrawToBitmap kannst du die PictureBox in ein Bitmap-Objekt zeichen lassen.

    Dim bmp As New Bitmap(Picturebox1.Width, PictureBox1.height)
    PictureBox1.DrawToBitmap(bmp,New Rectangle(0,0,PictureBox1.Width,PictureBox1.height))



    bmp in einem anderen Form verfügbar machen. Mit Public und As Bitmap komme ich da irgendwie nicht weiter... :S

    Auch mit dem Clipboard bekomme ich keine Lösung, denn wenn ich mehr als ein Bild ins Clipboard schreibe, weiß ich nicht wie ich auf ein spezielles Bild zugreife ???

    VB.NET-Quellcode

    1. My.Computer.Clipboard.GetImage(Bild1)

    Vielleicht so ähnlich? Habt Ihr da vielleicht noch ein paar Ideen?
    Also ich habe es jetzt nochmal mit dem Clipboard versucht und dort wird jeweils nur ein Bild gespeichert, das vorhergehende wird obwohl es einen anderen Namen hat überschrieben... ;(

    @tobikubi: Wie speicher ich denn Bilder im Ram und greife dann auf sie zu?

    Gruß, Tobias

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Panavia“ ()

    Das geht eigentlich schon mit Variablen. Da musst du Public statt Dim einsetzen und das direkt in die Klasse reinpacken. Der Zugriff läuft dann über [Klassenname].[Bild-Feldname]
    z.B:

    VB.NET-Quellcode

    1. Public Class xy
    2. Public bmp As Bitmap
    3. End Class
    4. Public Class blubb
    5. Public shared Function GetImage() As Bitmap
    6. Dim xy As New xy
    7. Return xy.bmp
    8. End Function
    9. End Class

    Das is zwar vielleicht ein recht dummes Beispiel aber so funzts im Prinzip.

    Gruß
    ~blaze~
    Hallo ~blaze~, danke für die Hilfe. Ich verstehe auch was Du meinst aber zum Laufen bekomme ich es trotzdem nicht... ;( Ich benutze ein PrintPreview Tool von ComponentOne, das das Bild in einer gewissen Form vorliegen haben muss. Vielleicht liegt es ja daran?

    Also momentan erstelle ich in einem Form ein mehrere "Abbilder" von verschiedenen PictureBoxen:

    VB.NET-Quellcode

    1. PictureBox.DrawToBitmap(Abbild1, New Rectangle(0, 0, PictureBox.Width, PictureBox.Height))

    Ich kann diese auf der Platte oder einzelne Bilder in der Zwischenablage speichern...
    In einem Anderen Form erstelle ich die PrintPreview und möchte hier auf die Abbilder zugreifen, diese einfügen und das nach Möglichkeit ohne sie auf der Platte zwischenspeichern zu müssen.
    Die Hilfedatei des Preview Tools gibt folgendes Codebeispiel wobei sie auf ein Bild in einer PictureBox1 zugreifen, was auch gut funktioniert.

    VB.NET-Quellcode

    1. Dim img1 As C1.C1PrintDocument.RenderImage = New C1.C1PrintDocument.RenderImage(Me.C1PrintDocument1)
    2. img1.Image = Me.PictureBox1.Image
    3. table.Body.Cell(1, 1).RenderObject = img1


    Ich muss also praktisch eine Verbindung zwischend den beiden oben stehenden Beispielen herstellen...
    Hatte auch schon daran gedacht mehere PictureBoxen in einem nicht sichtbaren Form als Zwischenspeicher zu nutzen finde das aber sehr unelegant...
    Hast Du da vielleicht eine Lösung?
    Gruß, Tobias
    Nee, leider nicht. Ich habe img1 wie folgt deklariert und rufe den Wert img1 in meiner Form, die den PrintPreview erstellt auf:

    VB.NET-Quellcode

    1. Public img1 As Bitmap

    und bekomme folgenden Fehler:
    "Fehler 1 Der Wert vom Typ "System.Drawing.Bitmap" kann nicht in "C1.C1PrintDocument.RenderObject" konvertiert werden."
    ... ?(
    So langsam geht mir die Geduld flöten. Ich hatte jetzt die Idee, ein Abbild der PictureBox zu erstellen, dieses als Image der PictureBox zu setzen und dann von dort heraus zu laden. Da die PictureBox aber während der Laufzeit Ihren Inhalt ändert und ich zu zwei verschiedenen Zeitpunkten diesen abgreifen muss, benötige ich zum einen eine Abfrage, ob das Form mit der entsprechenden PictureBox gerade angezeigt wird oder nicht und zum anderen eine Möglichkeit einen Public_Sub_CheckBox_CheckedChanged Event auslösen zu können, ohne letztendlich die CheckBox anzufassen...

    Oder kann ich vielleicht in einer PictrueBox mehrere Images "zwischanlagern" anstatt nur das Image und das BackgroundImage???
    Gruß, Tobias

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Panavia“ ()

    Ja klar. Also ich habe eine PictureBox in einem Form, die mit Linien, Gradienten und Polygonen etwas darstellt. Dieser Inhalt ist abhängig davon, was ich für Eingaben im Hauptform gemacht habe und ob eine oder eine andere CheckBox angewählt wurden. Nun kommt die Krux: Die PictureBox ist nur auf Anfrage des Nutzers sichtbar es sollen aber vier Abbilder mit verschiedenen Inhalten der PictureBox erstellt werden und mit dem PrintPreview Tool in das Dokument eingefügt werden.

    Das PrintPreview Tool ist Bestandteil des Hauptdokuments und generiert auf Knopfdruck ein Dokument in einem Preview Fenster. In dieses sollen wie gesagt die Bilder eingefügt werden. Ich habe nun schlichtweg das Problem die PictureBox in die vier verschiedenen Zustände zu versetzten, jeweils ein Abbild des jeweiligen Inhalts zu generieren und diese dann beim Erstellen des Dokuments einzufügen...

    Zusätzlich würde ich meinen Code gerne knapp und übersichtlich halten, da dieser noch in der Entwicklung ist und ich vermeiden möchte bei Weiterentwicklungen an hundert verschiedenen Stellen arbeiten zu müssen... (Momentan habe ich über 10000 Zeilen an Code...). Hierzu habe ich auch meine ganzen Public Variablen in einem eigenen Modul angegeben.

    Gruß, Tobias
    Ja, eine Funktion ist die wie oben beschrieben, um z.B. ein Bild in eine Tabellenzelle einzufügen... Die scheint das Bild aber nur in einem gewissen Format zu akzeptieren... z.B. indem man Bilder aus einer bestehenden PictureBox einfügt. Gibt es denn eine Möglichkeit mehrere Bilder in einer PictureBox zu "lagern".

    Gruß, Tobias
    Öhm eine PictureBox is eigentlich einfach nur ein solches Control:

    VB.NET-Quellcode

    1. Public Class PB
    2. Inherits Control
    3. Private imgImage As Image
    4. Public Property Image() As Image
    5. Get
    6. Return imgImage
    7. End Get
    8. Set(ByVal value As Image)
    9. imgImage = value
    10. End Set
    11. End Property
    12. Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
    13. MyBase.OnPaint(e)
    14. e.Graphics.DrawImage(Me.Image, 0, 0, Me.Width, Me.Height)
    15. End Sub

    Das is jetzt nur vereinfacht aber im Prinzip läufts so.
    ==> ist nur eine Klasse, die das was sie enthält veranschaulicht.

    Deshalb solltest du auch Variablen übergeben können ^^

    Gruß
    ~blaze~
    Ich kann mir gut vorstellen, dass das mit dem Tool zusammenhängt, das mit einigen Restriktionen daher kommt, weil die Entwickler nicht genug Felxibilität integriert haben. Ich habe mich jetzt dazu entschieden, zwei PictureBoxen zu integrieren, die für den Benutzer nicht sichtbar sind und darin nach und nach die vier benötigten Ansichten zu generieren... Ist zwar nicht die schönste und ökonomischte Programmiererei aber wird wohl gehen... :huh:

    Dazu noch zwei kleine Fragen:

    - Kann ich eine beliegbige Private Sub aufrufen wie z.B. Private Sub Form_Load() und wenn ja wie?

    - Bezieht sich die Private Sub Form_Load() auf den Programmstart oder auf das öffnen der Form mit Form.Show()? Also wann wird Sub Form_Load() Ausgeführt?

    Herzlichen Dank auf jeden Fall für eure Geduld und vor allem für Deine Bemühungen ~blaze~! Finde ich toll :!:

    Gruß, Tobias
    Wenn Form1 gestartet wird wird das Event aufgerufen.


    Das aufrufen eines solchen Subs geht auch:

    VB.NET-Quellcode

    1. Private Sub Form1_Load(Byval sender As Object, byval e as EventArgs) Handles Me.Load
    2. 'iwas
    3. End Sub
    4. Private Sub y()
    5. Form1_Load(Me, New Eventargs())
    6. End Sub


    Das ist eigentlich nur ein Sub, der dem EventHandler zugewiesen wurde. Der Eventhandler ist ein Delegat, der aufgerufen wird, sobald das Event eintritt. Das sieht man z.B. in C# sehr schön. In Vb ists leider eher nicht so sichtbar.

    Gruß
    ~blaze~
    Ja cool danke. Ich verzweifel mit dem Sch... noch.
    Alles wurde von mir so eingegeben, wie Du es beschrieben hast aber es funktioniert nicht...
    Also so sieht jetzt mein in Form2 Sub aus, der von Form1 aufgerufen werden soll:

    VB.NET-Quellcode

    1. Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Me.Load


    und das ist, was in Form1 geschrieben steht um den Sub in Form2 aufzurufen:

    VB.NET-Quellcode

    1. Form2_Load(Me, New EventArgs())


    Was ich bekomme ist folgende Fehlermeldung:
    "Der Name "Form2_Load" wurde nicht deklariert."

    Das ist echt zum verrückt werden... Das kommt davon, wenn man nicht genau versteht was man da macht und meistens nur per Copy/Paste code generiert...