2015-09-07 5 views
6

Ich versuche einen Screenshot/Bitmap meines Bildschirms zu erstellen. Ich schrieb diese Funktion:Einen Screenshot mit Graphics.CopyFromScreen mit 150% Skalierung erstellen

public static Bitmap CreateScreenshot(Rectangle bounds) 
{ 
    var bmpScreenshot = new Bitmap(bounds.Width, bounds.Height, 
            PixelFormat.Format32bppArgb); 
    var gfxScreenshot = Graphics.FromImage(bmpScreenshot); 
    gfxScreenshot.CopyFromScreen(bounds.X, bounds.Y, 
     0, 0, 
     new Size(bounds.Size.Width, bounds.Size.Height), 
     CopyPixelOperation.SourceCopy); 
    return bmpScreenshot; 
} 

Diese Funktion wird in meinem Overlay-Formular aufgerufen, das die Bitmap auf sich selbst zeichnen sollte. Ich verwende derzeit GDI + für den gesamten Prozess.

private void ScreenshotOverlay_Load(object sender, EventArgs e) 
{ 
    foreach (Screen screen in Screen.AllScreens) 
     Size += screen.Bounds.Size; 
    Location = Screen.PrimaryScreen.Bounds.Location; 

    _screenshot = BitmapHelper.CreateScreenshot(new Rectangle(new Point(0, 0), Size)); 
    Invalidate(); // The screenshot/bitmap is drawn here 
} 

Ja, ich entsorgen die Bitmap später, also keine Sorge. ;) Auf meinem Laptop und Desktop-Computer funktioniert das gut. Ich habe das mit verschiedenen Auflösungen getestet und die Berechnungen sind korrekt. Ich kann ein Bild des Bildschirms auf dem Formular sehen.

Das Problem beginnt mit der Oberfläche 3. Alle Elemente werden um den Faktor 1,5 (150%) skaliert. Dies bedeutet folglich, dass sich die DPI ändert. Wenn ich versuche, dort einen Screenshot zu machen, erfasst er nur den oberen linken Teil des Bildschirms, aber nicht den ganzen. Ich habe meinen Weg durch Google und Stackoverflow aus und probierte verschiedene Dinge:

  1. die DPI Erhalten, teilen sie durch 96 und die Größe Komponenten (X und Y) des Bildschirms mit diesem Faktor multiplizieren.
  2. Fügen Sie einen Eintrag zu application.manifest hinzu, um die Anwendung DPI-aware zu machen.

Der erste Weg brachte nicht das gewünschte Ergebnis. Der zweite Fall war der Fall, aber die gesamte Anwendung müsste angepasst werden, was in Windows Forms ziemlich kompliziert ist.

Jetzt meine Frage wäre: Gibt es eine Möglichkeit, einen Screenshot des gesamten Bildschirms zu erfassen, auch wenn es einen Skalierungsfaktor größer als 1 (höhere DPI) hat? Es muss einen Weg geben, dies zu tun, damit es überall funktioniert.

Aber an dieser Stelle hatte ich keine echten Suchergebnisse, die mir helfen könnten. Vielen Dank im Voraus.

+2

muß Es ist nicht „kompliziert“, man muss nur ein paar schlechten Gewohnheiten abgewöhnen . Könnte auch jetzt knacken, diese High-DPI-Monitore werden nicht weggehen. –

+1

@HansPassant Hm, okay. Dann kann ich wahrscheinlich nichts anderes tun, oder? Wenn ja, werde ich versuchen, meine Bewerbung vollständig DPI-bewusst zu machen. –

Antwort

1

Versuchen Sie dies, die in SharpAVI-Bibliothek gefunden wird. Es funktioniert gut auf Geräten unabhängig von der Auflösungsskala. Und ich habe es auf Oberfläche 3 bei 150% getestet.

SharpAVI sind hier zu finden: https://github.com/baSSiLL/SharpAvi Es ist für Videos ist aber eine ähnliche copyFromScreen Methode verwendet, wenn jedes Bild bekommen:

graphics.CopyFromScreen(0, 0, 0, 0, new System.Drawing.Size(screenWidth, screenHeight)); 
+1

Ich bin mir nicht sicher, warum ich hier eine Abstimmung bekommen habe. Derzeit ist es möglich, einen Screenshot mit einem Skalierungsfaktor von über 1 zu erstellen, ohne einen Eintrag zum App-Manifest hinzuzufügen. – ickydime

Verwandte Themen