如何使用 DPI 为 125% 的多台显示器修复 CopyFromScreen

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


我的问题是,当我从外接显示器移到笔记本电脑的主屏幕时,捕获区域移动的量不一致。我终于弄明白缩放比例 (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;

        }

    }


千万里不及你
浏览 115回答 2
2回答

心有法竹

我不确定您是如何使用当前代码复制屏幕的正确部分的。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);}不过,我不知道这是否能在不同的缩放模式下正常工作。

慕姐4208626

我找不到修复它的方法。我更改了方法并在表单上使用了 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;    }}
打开App,查看更多内容
随时随地看视频慕课网APP