Screenshots Anzeige auf unterschiedlich großen Screens

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 12 Antworten in diesem Thema. Der letzte Beitrag () ist von gluehbirne.

    Screenshots Anzeige auf unterschiedlich großen Screens

    Hi, ich habe zwei Formen. Form1 mit einem Button. Beim Klick auf den Button geht auf Screen2 eine Vollbildform (Form2) auf, die folgenden Code aufweist:

    VB.NET-Quellcode

    1. Public Class frmAusgabe
    2. Dim screenshot As System.Drawing.Bitmap
    3. Dim graph As Graphics
    4. Dim screen1, screen2 As Screen
    5. Public Sub frmAusgabe_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    6. Dim screen1, screen2 As Screen
    7. screen1 = Screen.PrimaryScreen
    8. screen2 = Screen.AllScreens(1)
    9. Me.Width = screen2.Bounds.Width
    10. Me.Height = screen2.Bounds.Height
    11. PicBox.Width = Me.Width
    12. PicBox.Height = Me.Height
    13. timerCapturing.Enabled = True
    14. End Sub
    15. Public Sub timerCapturing_Tick(sender As Object, e As EventArgs) Handles timerCapturing.Tick
    16. screenshot = New System.Drawing.Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
    17. graph = Graphics.FromImage(screenshot)
    18. graph.CopyFromScreen(0, 0, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy)
    19. 'Cursor.Draw(graph, New Rectangle(New Point(Cursor.Position.X - Cursor.HotSpot.X, Cursor.Position.Y - Cursor.HotSpot.Y), Cursor.Size))
    20. PicBox.Image = screenshot
    21. 'screenshot.Save("C:\Users\Testkuebel\Desktop\test.jpg", Imaging.ImageFormat.Jpeg)
    22. End Sub
    23. End Class


    Nun ist es so, dass nicht der vollständige Screen1 in dem Bild angezeigt wird. Beim Speichern des Screenshots ist es ebenfalls so. Daher gehe ich davon aus, dass die Screenshot-Erstellung schon irgendwie falsch ist. Allerdings komme ich seit Stunden nicht auf die Lösung. Hat jemand eine Idee?
    Bilder
    • test.jpg

      132,95 kB, 1.536×864, 75 mal angesehen
    @gluehbirne Verwende konsequent

    VB.NET-Quellcode

    1. screen1 = Screen.AllScreens(0)
    2. screen2 = Screen.AllScreens(1)
    nicht aber

    VB.NET-Quellcode

    1. Screen.PrimaryScreen.Bounds.XXX
    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!

    gluehbirne schrieb:

    mein Problem nicht gelöst
    Was genau soll passieren?
    Was passiert statt dessen?
    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!
    Es wird nicht der komplette Screen1 aufgenommen und somit auch nicht auf dem Screen2 komplett dargestellt. Zwar ist der Screen1 16:9 und der 2er 4:3, aber mein Ziel ist eben den kompletten Screen1 dann entsprechend mit Rändern auf dem 2er anzuzeigen.

    Versteht man mich?

    Ich habe den Code mal zurückgebaut. Nun habe ich einfach einen, der einen Screenshot des kompletten Screens machen soll. Schon alleine das klappt nicht. Es fehlt rechts und unten ein ganzes Stück (Taskleiste z.B.)

    Visual Basic-Quellcode

    1. Public Class frmHaupt
    2. Dim screenshot As System.Drawing.Bitmap
    3. Dim graph As Graphics
    4. Dim screen1 As Screen
    5. Dim sizeShot As Size
    6. Private Sub cmdDuplicate_Click(sender As Object, e As EventArgs) Handles cmdDuplicate.Click
    7. screen1 = Screen.AllScreens(0)
    8. screenshot = New System.Drawing.Bitmap(screen1.Bounds.Width, screen1.Bounds.Height, Imaging.PixelFormat.Format32bppArgb)
    9. graph = Graphics.FromImage(screenshot)
    10. graph.CopyFromScreen(0, 0, 0, 0, screen1.Bounds.Size, CopyPixelOperation.SourceCopy)
    11. screenshot.Save("C:\Users\Testkuebel\Desktop\test.jpg", Imaging.ImageFormat.Jpeg)
    12. End Sub
    13. End Class


    Ich komme einfach nicht drauf wo mein Fehler liegt...
    Bilder
    • test.jpg

      106,31 kB, 1.536×864, 63 mal angesehen

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

    gluehbirne schrieb:

    auf dem 2er anzuzeigen.
    Sind die gespeicherten Bilder korrekt?
    Mit welchem Code zeigst Du sie an?
    Welche Propertries hat die PictureBox, die das dargestellte Bild skalieren?
    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!
    Da der Code in Post#5 bei mir funktioniert und ich einen kompletten Screenshot inkl. Taskleiste hinbekomme, riecht das für mich nach Skalierung.
    Guck mal bei den Windows-Einstellungen -> System -> Anzeige -> Skalierung, ob da was anderes als 100% drinsteht. Denn wenn ja, wird's der von Dir beschriebene Murks.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @gluehbirne In Post #6 stehen noch unbeantwortete Fragen.
    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!

    RodFromGermany schrieb:

    Sind die gespeicherten Bilder korrekt?
    nein, das habe ich ja geschrieben und zwei Bilder in den Posts angehängt

    RodFromGermany schrieb:

    Mit welchem Code zeigst Du sie an?
    ohne code, Windows Fotoanzeige

    RodFromGermany schrieb:

    Welche Propertries hat die PictureBox, die das dargestellte Bild skalieren?
    das tut noch nichts zur Sache, da das gespeicherte JPEG bzw. BMP schon nicht korrekt ist. Somit liegt es nicht an der picturebox


    Das Problem liegt am skalieren. Wenn ich auf 100 Stelle, stimmt alles. Nur muss es auf 125 bleiben und ich suche somit eine Möglichkeit das zu handeln.

    „Inline“-Beantwortung der Fragen im Zitat auseinandergezogen. ~Thunderbolt

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

    Hallo @gluehbirne

    Versuche einmal das dpiAware einzuschalten.
    Diese werden in der app.manifest aktiviert.
    Allgemeine Anwendungseinstellungen -> Windows-Einstellungen anzeigen ->die <!-- vor dem Code und --> nach dem Code entfernen (XML-Kommentarzeichen)

    XML-Quellcode

    1. <application xmlns="urn:schemas-microsoft-com:asm.v3">
    2. <windowsSettings>
    3. <dpiAware xmlns="[url]http://schemas.microsoft.com/SMI/2005/WindowsSettings[/url]">true</dpiAware>
    4. </windowsSettings>
    5. </application>
    @HenryV Hat bei mir nicht geholfen, auch nicht mit dem App.config-Part:

    XML-Quellcode

    1. <appSettings>
    2. <add key="EnableWindowsFormsHighDpiAutoResizing" value="true" />
    3. </appSettings>

    gluehbirne schrieb:

    Nur muss es auf 125 bleiben
    Es würde gehen, wenn ich die 125 & Co auslesen könnte, was mir bisher noch nicht gelang.
    @All; Wie kann die 125 oder etwas äquivalentes ausgelesen werden?
    Bitte keinen ungetesteten Code posten, die 96 bekomme ich bei allen Einstellungen (100, 125, 150).
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    2. Me.AutoScaleMode = AutoScaleMode.Dpi '.Font '.Inherit '.None
    3. Dim gr = CreateGraphics()
    4. Dim dpiX = gr.DpiX
    5. Dim dpiY = gr.DpiY
    6. Label1.Text = String.Format("{0} x {1}", dpiX, dpiY)
    7. End Sub
    Der Screenshot funktioniert dann so:

    VB.NET-Quellcode

    1. Function Screenshot(index As Integer) As Bitmap
    2. Dim img As Bitmap
    3. Dim x0 As Integer
    4. If index = 0 Then
    5. ' Koordinaten des 1. Screens
    6. x0 = 0
    7. 'img = New Bitmap(Screen.AllScreens(0).Bounds.Width * 5 \ 4, Screen.AllScreens(0).Bounds.Height * 5 \ 4)
    8. img = New Bitmap(Screen.AllScreens(0).Bounds.Width, Screen.AllScreens(0).Bounds.Height)
    9. Else
    10. ' Koordinaten des 2. Screens
    11. x0 = Screen.AllScreens(1).Bounds.X
    12. img = New Bitmap(Screen.AllScreens(1).Bounds.Width, Screen.AllScreens(1).Bounds.Height)
    13. End If
    14. Using g As Graphics = Graphics.FromImage(img)
    15. g.CopyFromScreen(x0, 0, 0, 0, img.Size)
    16. g.Dispose()
    17. End Using
    18. Return img
    19. End Function

    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!
    Hallo, habe eine Lösung gefunden. Zumindest erkennt er die unterschiedlichen Skalierungseinstellungen nach einem Neustart korrekt. Da ich davon ausgehe, dass die User nicht permanent ändern, soll es mir so recht sein. Ich kann mir aber nicht genau erklären, weshalb es so nun funktioniert:

    Visual Basic-Quellcode

    1. ​Imports System.Runtime.InteropServices
    2. Public Class frmHaupt
    3. <DllImport("User32.dll")>
    4. Private Shared Sub SetProcessDPIAware()
    5. End Sub
    6. Dim screenshot As System.Drawing.Bitmap
    7. Dim graph As Graphics
    8. Dim screen1 As Screen
    9. Dim bounds As Rectangle
    10. Dim DPIScalingX As Integer
    11. Dim DPIScalingY As Integer
    12. Private Sub cmdDuplicate_Click(sender As Object, e As EventArgs) Handles cmdDuplicate.Click
    13. screen1 = Screen.AllScreens(0)
    14. bounds = screen1.Bounds
    15. bounds.Width = screen1.Bounds.Width
    16. bounds.Height = screen1.Bounds.Height
    17. screenshot = New System.Drawing.Bitmap(bounds.Width, bounds.Height, Imaging.PixelFormat.Format32bppArgb)
    18. graph = Graphics.FromImage(screenshot)
    19. graph.CopyFromScreen(0, 0, 0, 0, bounds.Size, CopyPixelOperation.SourceCopy)
    20. screenshot.Save("C:\Users\Testkuebel\Desktop\test.jpg", Imaging.ImageFormat.Bmp)
    21. End Sub
    22. Private Sub frmHaupt_Load(sender As Object, e As EventArgs) Handles Me.Load
    23. SetProcessDPIAware()
    24. DPIScalingX = Me.CreateGraphics().DpiX / 96
    25. DPIScalingY = Me.CreateGraphics().DpiY / 96
    26. End Sub
    27. End Class