# C# windows GDI 截屏

代码

C#
private byte[] ScreenCapture(out int length)
{
    length = 0;
    if (OperatingSystem.IsWindows())
    {
        IntPtr hdc = GetDC(IntPtr.Zero);
        if (hdc != IntPtr.Zero)
        {
            using Bitmap source = new Bitmap(GetDeviceCaps(hdc, DESKTOPHORZRES), GetDeviceCaps(hdc, DESKTOPVERTRES));
            using (Graphics g = Graphics.FromImage(source))
            {
                g.CopyFromScreen(0, 0, 0, 0, source.Size, CopyPixelOperation.SourceCopy);
                
                //绘制鼠标
                CURSORINFO pci;
                pci.cbSize = Marshal.SizeOf(typeof(CURSORINFO));
                if (GetCursorInfo(out pci))
                {
                    if (pci.flags == CURSOR_SHOWING)
                    {
                        var hdc1 = g.GetHdc();
                        DrawIconEx(hdc1, pci.ptScreenPos.x - 0, pci.ptScreenPos.y - 0, pci.hCursor, 0, 0, 0, IntPtr.Zero, DI_NORMAL);
                        g.ReleaseHdc();
                    }
                }

                g.Dispose();
            }
            ReleaseDC(IntPtr.Zero, hdc);

            //转为1/5小图
            int newWidth = (int)(source.Width * 0.2);
            int newHeight = (int)(source.Height * 0.2);
            Bitmap bmp = new Bitmap(newWidth, newHeight);
            bmp.SetResolution(source.HorizontalResolution, source.VerticalResolution);
            using Graphics graphic = Graphics.FromImage(bmp);
            graphic.SmoothingMode = SmoothingMode.HighQuality;
            graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
            graphic.DrawImage(source, new Rectangle(0, 0, newWidth, newHeight));

            using Image image = bmp;
            
            //压缩为jpg
            using MemoryStream ms = new MemoryStream();
            image.Save(ms, ImageFormat.Jpeg);
            ms.Seek(0, SeekOrigin.Begin);

            length = (int)ms.Length;

            byte[] bytes = ArrayPool<byte>.Shared.Rent((int)ms.Length);
            ms.Read(bytes);
            return bytes;
        }
    }

    return Array.Empty<byte>();
}
private void Return(byte[] bytes)
{
    ArrayPool<byte>.Shared.Return(bytes);
}


const int DESKTOPVERTRES = 117;
const int DESKTOPHORZRES = 118;

[DllImport("user32.dll")]
static extern IntPtr GetDC(IntPtr ptr);

[DllImport("user32.dll", EntryPoint = "ReleaseDC")]
static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc);

[DllImport("gdi32.dll", EntryPoint = "GetDeviceCaps", SetLastError = true)]
public static extern int GetDeviceCaps(IntPtr hdc, int nIndex);

[DllImport("user32.dll", EntryPoint = "GetSystemMetrics")]
private static extern int GetSystemMetrics(int mVal);

[StructLayout(LayoutKind.Sequential)]
private struct CURSORINFO
        {
            public Int32 cbSize;
            public Int32 flags;
            public IntPtr hCursor;
            public POINTAPI ptScreenPos;
        }

[StructLayout(LayoutKind.Sequential)]
private struct POINTAPI
        {
            public int x;
            public int y;
        }
private const Int32 CURSOR_SHOWING = 0x0001;
private const Int32 DI_NORMAL = 0x0003;

[DllImport("user32.dll")]
private static extern bool GetCursorInfo(out CURSORINFO pci);

[DllImport("user32.dll", SetLastError = true)]
static extern bool DrawIconEx(IntPtr hdc, int xLeft, int yTop, IntPtr hIcon, int cxWidth, int cyHeight, int istepIfAniCur, IntPtr hbrFlickerFreeDraw, int diFlags);