Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Graphics.CopyFromScreen以150%的比例拍摄屏幕截图_C#_.net_Bitmap - Fatal编程技术网

C# 使用Graphics.CopyFromScreen以150%的比例拍摄屏幕截图

C# 使用Graphics.CopyFromScreen以150%的比例拍摄屏幕截图,c#,.net,bitmap,C#,.net,Bitmap,我正在尝试创建屏幕截图/位图。我写了这个函数: public static Bitmap CreateScreenshot(Rectangle bounds) { var bmpScreenshot = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format32bppArgb); var gfxScreenshot = Graphics.FromI

我正在尝试创建屏幕截图/位图。我写了这个函数:

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;
}
这个函数在我的叠加表单中被调用,它应该将位图绘制到自身上。我目前正在整个过程中使用GDI+

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
}
是的,我稍后会处理位图,所以不用担心。;) 在我的笔记本电脑和台式电脑上,这很好用。我用不同的分辨率进行了测试,计算结果是正确的。我可以在表单上看到屏幕的图像

问题从曲面3开始。所有元素的比例均为1.5(150%)。因此,这意味着DPI发生变化。如果我试着在那里截图,它只截取屏幕左上部分,而不是整个屏幕。 我通过Google和StackOverflow尝试了不同的方法:

  • 获取DPI,将其除以96,然后将屏幕的大小分量(X和Y)乘以该因子
  • 向application.manifest添加一个条目以使应用程序DPI感知
  • 第一种方法没有达到预期的效果。第二个是这样的,但整个应用程序将不得不进行调整,这在Windows窗体中相当复杂

    现在我的问题是:是否有任何方法可以捕获整个屏幕的截图,即使它的缩放因子大于1(更高的DPI)? 必须有办法做到这一点,以使它在任何地方都能发挥作用

    但在这一点上,我没有真正的搜索结果可以帮助我。
    提前感谢。

    试试这个,可以在夏帕维图书馆找到。无论分辨率大小,它都能在设备上正常工作。我已经在表面3上以150%的速度进行了测试

    System.Windows.Media.Matrix toDevice;
    using (var source = new HwndSource(new HwndSourceParameters()))
    {
        toDevice = source.CompositionTarget.TransformToDevice;
    }
    screenWidth = (int)Math.Round(SystemParameters.PrimaryScreenWidth * toDevice.M11);
    screenHeight = (int)Math.Round(SystemParameters.PrimaryScreenHeight * toDevice.M22);
    
    SharpAVI可在此处找到:它用于视频,但在获取每个帧时使用类似的copyFromScreen方法:

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

    在进行屏幕截图之前,您可以让流程DPI意识到:

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern bool SetProcessDPIAware();
    
    private static Bitmap Screenshot()
    {
        SetProcessDPIAware();
        var screen = System.Windows.Forms.Screen.PrimaryScreen;
        var rect = screen.Bounds;
        var size = rect.Size;
    
        Bitmap bmpScreenshot = new Bitmap(size.Width, size.Height);
        Graphics g = Graphics.FromImage(bmpScreenshot);
        g.CopyFromScreen(0, 0, 0, 0, size);
    
        return bmpScreenshot;
    }
    

    这并不“复杂”,你只需要改掉一些坏习惯。也许现在就开始吧,那些高DPI监视器不会消失。@HansPassant Hm,好的。那我就没办法了,对吗?如果是这样的话,我会尽量让我的应用程序完全支持DPI。我不知道为什么我会在这里投反对票。当前可以获取比例因子大于1的屏幕截图,而无需向应用程序清单添加条目。注意:user32.dll在Win7中不可用。@m.qayyum为什么说user32.dll在Win7中不可用?我认为user32在Win7、8、10中始终可用,而不管它是32位还是64位系统。根据Microsoft文档,user32.dll自Windows NT 4.0以来一直可用,因此包括Windows NT、XP、Vista、7、8和10。通常,服务器版本具有相同的OS文件。