How to use Control.DrawToBitmap to render a Form into a Bitmap without its decorations (titlebar, border)? [duplicate]

妖精的绣舞 提交于 2019-12-11 10:43:51

问题


I have a Form and in it an Overlay control (transparent gray backcolor with White text over "Drop here..." and an icon) that is visible only when a file is dragged over the Form. The Overlay is made transparent by drawing the control in its back on it and then filling over with transparent gray (ARGB). The method Works very well when the Overlay should be over a Control that is not a Form, but when I use Control.DrawToBitmap to render a Form, not an usual Control, it also renders the title bar and border.


回答1:


Form.DrawToBitmap draws the whole form including non-client area. You can use BitBlt. The BitBlt function performs a bit-block transfer of the color data corresponding to a rectangle of pixels from the specified source device context into a destination device context.

const int SRCCOPY = 0xCC0020;
[DllImport("gdi32.dll")]
static extern int BitBlt(IntPtr hdc, int x, int y, int cx, int cy,
    IntPtr hdcSrc, int x1, int y1, int rop);

Image PrintClientRectangleToImage()
{
    var bmp = new Bitmap(ClientSize.Width, ClientSize.Height);
    using (var bmpGraphics = Graphics.FromImage(bmp))
    {
        var bmpDC = bmpGraphics.GetHdc();
        using (Graphics formGraphics = Graphics.FromHwnd(this.Handle))
        {
            var formDC = formGraphics.GetHdc();
            BitBlt(bmpDC, 0, 0, ClientSize.Width, ClientSize.Height, formDC, 0, 0, SRCCOPY);
            formGraphics.ReleaseHdc(formDC);
        }
        bmpGraphics.ReleaseHdc(bmpDC);
    }
    return bmp;
}



回答2:


The Control.DrawToBitmap method always return a Bitmap drawn from the upper-left corner of the control, even if you pass the method a Rectangle with specific bounds.

Here, the ClientRectangle portion of a Form is translated using the Size of its Bounds.

Note that, if your application is not DPIAware, you might get wrong measures from all the methods that return a Point or a Rectangle. Non-DPIAware Windows API included.

If you need to save the resulting Bitmap, use PNG as the destination format: its loss-less compression is better suited for this kind of rendering.

Call this method with the ClientAreaOnly argument set to true to have it return a Bitmap of the ClientArea only.

public Bitmap FormScreenShot(Form form, bool ClientAreaOnly)
{
    Bitmap fullSizeBitmap = new Bitmap(form.Width, form.Height, PixelFormat.Format32bppArgb);
    //.Net 4.7+
    //fullSizeBitmap.SetResolution(form.DeviceDpi, form.DeviceDpi);

    form.DrawToBitmap(fullSizeBitmap, new Rectangle(Point.Empty, form.Size));
    if (ClientAreaOnly) return fullSizeBitmap;

    Point p = form.PointToScreen(Point.Empty);
    Rectangle clientRect =
        new Rectangle(new Point(p.X - form.Bounds.X, p.Y - form.Bounds.Y), form.ClientSize);

    Bitmap clientAreBitmap = fullSizeBitmap.Clone(clientRect, PixelFormat.Format32bppArgb);
    fullSizeBitmap.Dispose();
    return (Bitmap)clientAreBitmap.Clone();
}



回答3:


You could render the whole form and then take only the part you need with Bitmap.Clone(). Here you have explained how to do it.



来源:https://stackoverflow.com/questions/54628992/how-to-use-control-drawtobitmap-to-render-a-form-into-a-bitmap-without-its-decor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!