【问题标题】:How to fix CopyFromScreen using multiple monitors with DPI of 125%如何使用 DPI 为 125% 的多台显示器修复 CopyFromScreen
【发布时间】:2019-06-28 21:22:10
【问题描述】:

我编写了一个函数,它将获取一个控件和一个文件目标,并将保存控件所覆盖的表单区域。

我的问题是,当我从外接显示器移动到笔记本电脑的主屏幕时,捕获区域的移动量不一致。我终于发现缩放(DPI)是罪魁祸首。当我将其更改为 100% (96 DPI) 时,它可以在笔记本电脑屏幕上运行。所有其他屏幕都已设置为 100%。回到 125%,这只是笔记本电脑屏幕上的问题。如何允许 125%?

在笔记本电脑屏幕上,表格越靠近屏幕左上角,图像的位置就越准确。生成的图像大小在任何屏幕上都是相同的,只是在笔记本电脑屏幕上位置会发生变化。此外,当我从外接显示器转换到笔记本电脑显示器时,表单会调整大小。正是在调整大小之后,我才得到了这个问题。

    private void capture(Control ctrl, string fileName)
    {
        Rectangle bounds = ctrl.Bounds;
        Point pt = ctrl.PointToScreen(bounds.Location);
        Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height);
        using (Graphics g = Graphics.FromImage(bitmap))
        {
            g.CopyFromScreen(new Point(pt.X - ctrl.Location.X, pt.Y - ctrl.Location.Y), Point.Empty, bounds.Size);
        }
        string filetype = fileName.Substring(fileName.LastIndexOf('.')).ToLower();
        switch (filetype)
        {
            case ".png":
                bitmap.Save(fileName, ImageFormat.Png);
                break;
            case ".jpeg":
                bitmap.Save(fileName, ImageFormat.Jpeg);
                break;
            case ".bmp":
                bitmap.Save(fileName, ImageFormat.Bmp);
                break;
            default:
                break;
        }
    }

【问题讨论】:

    标签: c# dpi


    【解决方案1】:

    我不确定您是如何使用当前代码复制正确的屏幕部分的。 Bounds() 属性返回一个与 PARENT 控件相关的矩形,但您要求控件本身(不是父级)转换为屏幕坐标:

    获取或设置控件的大小和位置,包括其 相对于父控件的非客户端元素,以像素为单位。

    我希望看到更多类似的东西:

    Rectangle bounds = ctrl.Parent.RectangleToScreen(ctrl.Bounds);       
    Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height);
    using (Graphics g = Graphics.FromImage(bitmap))
    {
        g.CopyFromScreen(bounds.Location, new Point(0,0), bounds.Size);
    }
    

    不过,我不知道这是否能在不同的缩放模式下正常工作。

    【讨论】:

    • 我更新了代码,问题没有改变。我将使用可能有助于指出问题的更多信息更新我的问题。
    【解决方案2】:

    我找不到修复它的方法。我更改了方法并在表单上使用了 DrawToBitmap,然后从控件位置制作了一个图像。我必须考虑一个固定的偏移量。我认为这与顶部栏包含在表单的位图中而不包含在表单中控件的位置有关。

    要考虑的一件事是 DrawToBitmap 以相反的堆栈顺序绘制。如果您有重叠的对象,您可能需要颠倒 DrawToBitmap 的顺序。

    private void capture(Control ctrl, string fileName)
    {
        Bitmap bitmapForm = new Bitmap(this.Width, this.Height);
        this.DrawToBitmap(bitmapForm, new Rectangle(0, 0, this.Width, this.Height));
        Rectangle myControlRect = new Rectangle(ctrl.Location,ctrl.Size);
        //Correct for boarder around form
        myControlRect.Offset(8,31);
        Bitmap bitmap = bitmapForm.Clone(myControlRect, PixelFormat.DontCare);
        string filetype = fileName.Substring(fileName.LastIndexOf('.')).ToLower();
        switch (filetype)
        {
            case ".png":
                bitmap.Save(fileName, ImageFormat.Png);
                break;
            case ".jpeg":
                bitmap.Save(fileName, ImageFormat.Jpeg);
                break;
            case ".bmp":
                bitmap.Save(fileName, ImageFormat.Bmp);
                break;
            default:
                break;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-10
      • 2022-01-10
      • 2021-10-18
      • 1970-01-01
      • 2020-03-01
      • 1970-01-01
      • 2011-06-10
      相关资源
      最近更新 更多