开发者

How would I go about taking a snapshot of a portion of my application's window?

I'm currently attempting to take snapshot of a specified portion of my application's window from a specified starting coordinate (which is where my problem comes in).

Rectangle bounds = new Rectangle((this.Width/2)-400,(this.Height/2)-200, 800,400);

using (Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format32bppArgb))
{   
    using (Graphics graphics开发者_开发技巧 = Graphics.FromImage(bitmap))
    {
        IntPtr hdc = graphics.GetHdc();
        PrintWindow(this.axS.Handle, hdc, 0);
        graphics.ReleaseHdc(hdc);
        graphics.Flush();
        string file = "example.png";
        bitmap.Save(file, ImageFormat.Png);
    }
}

I'm attempting to make a dynamic-adaptive method to take a screenshot of the center of the window, even after being resized. I'm not sure how to apply x and y to the screenshot as a starting point for the screenshot. Dimensions will always remain 800,400 and always taking a screenshot of the center of the application regardless of window size.

Every attempt I have pegged, the bitmap took a screenshot from 0 (+800), 0 (+400) where 0, 0 I need to change.

Is Bitmap capable of this? If not, what other method could I use?


You can use SetViewportOrgEx to set the origin on the HDC. I found that the title bar of the window was throwing off the calculation of the center point, so I took that into account as well.

int x = (this.Width / 2) - 400;
int y = ((this.Height + SystemInformation.CaptionHeight) / 2) - 200;

Rectangle bounds = new Rectangle(x, y, 800, 400);

using (Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format32bppArgb))
{
    using (Graphics graphics = Graphics.FromImage(bitmap))
    {
        IntPtr hdc = graphics.GetHdc();
        POINT pt;

        SetViewportOrgEx(hdc, -x, -y, out pt);

        // rest as before
    }
}

And the signatures for SetViewportOrgEx and POINT:

[DllImport("gdi32.dll")]
static extern bool SetViewportOrgEx(IntPtr hdc, int X, int Y, out POINT lpPoint);

[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
    public int X;
    public int Y;

    public POINT(int x, int y)
    {
        this.X = x;
        this.Y = y;
    }

    public static implicit operator System.Drawing.Point(POINT p)
    {
        return new System.Drawing.Point(p.X, p.Y);
    }

    public static implicit operator POINT(System.Drawing.Point p)
    {
        return new POINT(p.X, p.Y);
    }
}


Instead of using PrintWindow try using Graphics.CopyFromScreen which allows you to specify both an upper-left corner as well as dimensions.

http://msdn.microsoft.com/en-us/library/6yfzc507.aspx

Performs a bit-block transfer of color data, corresponding to a rectangle of pixels, from the screen to the drawing surface of the Graphics.

CopyFromScreen works on screen coordinates so you'll have to calculate that for the call.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜