How do I draw the outline of a collection of rectangles?

痞子三分冷 提交于 2019-12-05 17:18:39

I'm still not entirely sure I understand the question. However, it sounds to me as though you simply want to draw the given region by outlining it, rather than filling it.

Unfortunately, as far as I know the .NET API does not support this. However, the native Windows API does. Here is some code that should do what you want:

[DllImport("gdi32")]
static extern bool FrameRgn(System.IntPtr hDC, System.IntPtr hRgn, IntPtr hBrush, int nWidth, int nHeight);

[DllImport("gdi32")]
static extern IntPtr CreateSolidBrush(uint colorref);

[DllImport("gdi32.dll")]
static extern bool DeleteObject([In] IntPtr hObject);

[StructLayout(LayoutKind.Explicit)]
struct COLORREF
{
    [FieldOffset(0)]
    public uint colorref;
    [FieldOffset(0)]
    public byte red;
    [FieldOffset(1)]
    public byte green;
    [FieldOffset(2)]
    public byte blue;

    public COLORREF(Color color)
        : this()
    {
        red = color.R;
        green = color.G;
        blue = color.B;
    }
}

void DrawRegion(Graphics graphics, Color color, Region region)
{
    COLORREF colorref = new COLORREF(color);
    IntPtr hdc = IntPtr.Zero, hbrush = IntPtr.Zero, hrgn = IntPtr.Zero;

    try
    {
        hrgn = region.GetHrgn(graphics);
        hdc = graphics.GetHdc();
        hbrush = CreateSolidBrush(colorref.colorref);

        FrameRgn(hdc, hrgn, hbrush, 1, 1);
    }
    finally
    {
        if (hrgn != IntPtr.Zero)
        {
            region.ReleaseHrgn(hrgn);
        }

        if (hbrush != IntPtr.Zero)
        {
            DeleteObject(hbrush);
        }

        if (hdc != IntPtr.Zero)
        {
            graphics.ReleaseHdc(hdc);
        }
    }
}

Call the DrawRegion() method from your Paint event handler or other appropriate context where you have a Graphics instance, such as drawing into an Image object as in your example.

Obviously you could make this an extension method for more convenience. Also, while in this example I am dealing with the initialization and releasing of the handles directly, a better implementation would wrap the handles in appropriate SafeHandle subclasses, so that you can conveniently use using instead of try/finally, and to get the backup of finalization (in case you forget to dispose).

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