Screenshot vom Programm erstellen und als Bilddatei speichern

  • VB.NET

Es gibt 18 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Screenshot vom Programm erstellen und als Bilddatei speichern

    Hallo zusammen,

    wie die Überschrift schon sagt, möchte ich gerne einen Screenshot von meinem Programm erstellen und diesen als Bilddatei abspeichern.
    Im Anhang findet ihr ein Bild von meinem Programm, wie es im moment aussieht.

    ich habe es mit ein wenig hilfe schon geschafft, dass das speichern funktioniert, aber ich habe noch ein problem die es zu beheben gilt.

    Hier erstmal mein Code:

    VB.NET-Quellcode

    1. Dim scr As Bitmap
    2. Dim w As Integer = Me.Width
    3. Dim h As Integer = Me.Height
    4. scr = New Bitmap(w, h)
    5. Me.DrawToBitmap(scr, Rectangle.FromLTRB(0, 0, w, h))
    6. SaveFileDialog2.ShowDialog()
    7. If SaveFileDialog2.FileName = "" Then
    8. SaveFileDialog2.ShowDialog()
    9. Else
    10. scr.Save(SaveFileDialog2.FileName)
    11. End If


    Das Problem ist, das bei dem gespeichertem Screenshot der Inhalt des Panels nicht mit abgebildet wird.


    Würde mich über ein paar tipps freuen
    Bilder
    • Unbenannt.png

      304,25 kB, 1.600×900, 1.161 mal angesehen

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

    Dann musst du wohl diesen Teil extra Speichern, da das wahrscheinlich mit GDI+ gezeichnet wird und somit wohl ignoriert wird ;)(Was mich allerdings sehr wundert...xD)
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---

    VB.NET-Quellcode

    1. Using gr As Graphics = Graphics.FromImage(scr)
    2. 'Hier nochmal die Zeichnung auf das gr-Graphics-Objekt anwenden(Jedoch müssen die Koordinaten der Position relativ zum Formular umgerechnet werden)
    3. End Using
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    was heißt denn die koordinaten relativ zum Formular umrechenen?

    Ich hab sowas noch nie gemacht bzw. noch nie mit sowas gearbeitet

    gibt es da vielleicht noch andere Möglichkeiten?

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

    Probier mal dies:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Runtime.InteropServices
    2. Public Class Form1
    3. <StructLayout(LayoutKind.Sequential)>
    4. Public Structure POINTAPI
    5. Public x As Integer
    6. Public y As Integer
    7. End Structure
    8. <DllImport("user32.dll")> _
    9. Public Shared Function ClientToScreen(ByVal hWnd As IntPtr, ByRef pt As POINTAPI) As Integer
    10. End Function
    11. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    12. Dim bmp As New Bitmap(Me.Width, Me.Height)
    13. Dim g As Graphics = Graphics.FromImage(bmp)
    14. Dim pt As POINTAPI
    15. pt.x = -7 ' Rand-Breite, kannst Du über API-Funktionen auslelen
    16. pt.y = -30 ' Titelzeilen-Höhe, kannst Du über API-Funktionen auslelen
    17. ClientToScreen(Me.Handle, pt)
    18. g.CopyFromScreen(pt.X, pt.Y, 0, 0, Me.Size)
    19. g.Dispose()
    20. bmp.Save("c:\Temp\Shot.bmp", System.Drawing.Imaging.ImageFormat.Bmp)
    21. End Sub
    22. End Class
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Kein Problem. Aber
    Wo soll denn die Straße hinführen? :D :D :D
    Rod
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    1 Savedialog

    Code

    Savedialog1.showdialog
    picturebox1.image = savedialog1.image

    es kann auch als fehler angezeigt werden und dieser code aknn benötickt werden

    Code


    Savedialog1.showdialog
    picturebox1.image = savedialog1.showdialog
    okay jetzt habe ich nochmal ein ähnliches Problem und wollte mal fragen ob man das theoretisch genau so lösen kann.

    Ich will jetzt die komplette form ausdrucken lassen und wie bei dem Speichern auch druckt er alles bis auf den Inhalt des Panels.

    VB.NET-Quellcode

    1. Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, _
    2. ByVal e As System.Drawing.Printing.PrintPageEventArgs) _
    3. Handles PrintDocument1.PrintPage
    4. Dim bmp As New Bitmap(Me.Width, Me.Height)
    5. Me.DrawToBitmap(bmp, New Rectangle(0, 0, Me.Width, Me.Height))
    6. e.Graphics.DrawImage(bmp, 0, 0)
    7. End Sub
    8. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    9. If PrintDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
    10. PrintDocument1.Print()
    11. End If
    12. End Sub
    13. End Class


    Hat jemand n tipp dafür oder wäre es ratsam einen neues Thema zu erstellen?
    Funktioniert.
    Drucke Deine Dokumente in eine PDF, da siehst Du den Erfolg sofort.
    Oder nutze den PrintPreviewDialog, da siehst Du den Erfolg sogar noch schneller.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    VB.NET-Quellcode

    1. Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    2. Using dlg As New PrintPreviewDialog
    3. dlg.Document = Me.PrintDocument1 ' das aus Deinem Projekt
    4. dlg.ShowDialog()
    5. End Using
    6. End Sub
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Du musst Dein Bild im Paint-Ereignis des Paness malen:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, _
    3. ByVal e As System.Drawing.Printing.PrintPageEventArgs) _
    4. Handles PrintDocument1.PrintPage
    5. Dim bmp As New Bitmap(Me.Width, Me.Height)
    6. Me.DrawToBitmap(bmp, New Rectangle(0, 0, Me.Width, Me.Height))
    7. e.Graphics.DrawImage(bmp, 0, 0)
    8. End Sub
    9. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    10. Using dlg As New PrintPreviewDialog
    11. dlg.Document = Me.PrintDocument1
    12. dlg.ShowDialog()
    13. End Using
    14. End Sub
    15. Private Sub Panel1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Panel1.Paint
    16. Dim g As Graphics = e.Graphics
    17. g.DrawEllipse(Pens.Black, New Rectangle(10, 10, 100, 100))
    18. End Sub
    19. End Class
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Kann ich die POINTAPI Funktion die auch den Screenshot erstellt nicht einfach mit
    meinem Printdialog verknüpfen?

    ich hab da mal n bisschen rumprobiert aber ich bekomme das nicht wirklich hin.

    ich hab spaßeshalber einfach mal folgendes gemacht

    VB.NET-Quellcode

    1. Dim bmp As New Bitmap(Me.Width, Me.Height)
    2. Dim g As Graphics = Graphics.FromImage(bmp)
    3. Dim pt As POINTAPI
    4. pt.x = -7
    5. pt.y = -30
    6. ClientToScreen(Me.Handle, pt)
    7. g.CopyFromScreen(pt.x, pt.y, 0, 0, Me.Size)
    8. Dim gr As Graphics = e.Graphics
    9. gr.DrawImage(bmp, 0, 0)
    10. e.HasMorePages = False
    11. g.Dispose()


    aber dann sieht das druckresultat so aus wir im anhang

    tipps?
    Bilder
    • Unbenannt2.png

      187,82 kB, 1.600×900, 751 mal angesehen
    Ein Bekannter von mir hat mir einen code gegebn, mit dem man das anscheinen mit der BitBlt funktion lösen kann.

    folgenden code hat er mir geschickt:

    VB.NET-Quellcode

    1. <DllImport("gdi32.DLL", EntryPoint:="BitBlt", _
    2. SetLastError:=True, CharSet:=CharSet.Unicode, _
    3. ExactSpelling:=True, _
    4. CallingConvention:=CallingConvention.StdCall)> _
    5. Private Shared Function BitBlt(ByVal hdcDest As IntPtr, _
    6. ByVal nXDest As Integer, ByVal nYDest As Integer, ByVal nWidth As Integer, _
    7. ByVal nHeight As Integer, ByVal hdcSrc As IntPtr, ByVal nXSrc As Integer, _
    8. ByVal nYSrc As Integer, ByVal dwRop As System.Int32) As Boolean
    9. End Function
    10. Function CaptureForm1() As Bitmap
    11. Dim g1 As Graphics = Me.CreateGraphics()
    12. Dim MyImage = New Bitmap(Me.Width, Me.ClientRectangle.Height, g1)
    13. Dim g2 As Graphics = Graphics.FromImage(MyImage)
    14. Dim dc1 As IntPtr = g1.GetHdc()
    15. Dim dc2 As IntPtr = g2.GetHdc()
    16. BitBlt(dc2, 0, 0, Me.Width, Me.ClientRectangle.Height, dc1, 0, 0, 13369376)
    17. g1.ReleaseHdc(dc1)
    18. g2.ReleaseHdc(dc2)
    19. MyImage.Save("c:\abc.bmp")
    20. Return MyImage
    21. End Function


    Hier noch der teil der zum Druck event gehört

    VB.NET-Quellcode

    1. Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
    2. img = CaptureForm1()
    3. Dim x As Integer = e.MarginBounds.X
    4. Dim y As Integer = e.MarginBounds.Y
    5. e.Graphics.DrawImage(img, x, y)
    6. e.HasMorePages = False
    7. End Sub


    allerdings ist das ne ecke zu komplex für und ich versteh das nich alles so ganz.
    im Anhang ist wieder ein Bild von dem derzeitigen stand.

    Das bild ist nach unten rechts gewandert, aber es sollte eigentlich oben links sein und das komplette blatt ausfüllen.

    ich habe versucht zu verstehen wie diese funktion arbeitet und an welcher stelle ich was ändern muss, aber da steh ich noch ziemlich aufm schlauch.
    Bilder
    • Unbenannt3.png

      203,85 kB, 1.600×900, 666 mal angesehen
    Du solltest mal ohna Zwang und in einem kleinen separaten Projekt meinen Code oben ausprobieren, damit Du verstehst, wie das Paint-Ereignis funktioniert.
    Dann wärst Du nämlich schon fertig.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!