You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# WinForms:提取子矩形并移动至(0,0)位置

问题:提取局部矩形并移动到(0,0)位置

需求:开发Windows Forms应用,从覆盖全屏的第一个矩形中提取第二个局部矩形,并将该局部矩形的内容移动到(0,0)位置。

当前效果

源效果

期望效果

期望结果

原代码

namespace ClipWindowsFormsApplication
{
partial class Form1
{
    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

    #region Windows Form Designer generated code

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
        this.SuspendLayout();
        // 
        // Form1
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(725, 509);
        this.Name = "Form1";
        this.Text = "Form1";
        this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);
        this.ResumeLayout(false);

    }

    #endregion
}
}


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ClipWindowsFormsApplication
{
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }



    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        Graphics g = e.Graphics;
        g.Clear(this.BackColor);

        //Create rectangles and regions
        Rectangle rect1 = new Rectangle(0, 0, 500, 500);
        Rectangle rect2 = new Rectangle(0, 100, 500, 200);
        Region r1 = new Region(rect1);
        Region r2 = new Region(rect2);

        //Call SetClip
        g.SetClip(r1, CombineMode.Intersect);

        g.DrawString("THIS IS GOING TO BE DELETED", this.Font, Brushes.Black, rect1);

        //Call IntersectClip
        g.IntersectClip(r2);

        //Fill rectangle
        g.FillRectangle(Brushes.Magenta, 0, 0, 500, 300);

        g.DrawString("TEST MY APP", this.Font, Brushes.White, rect2);

        //Call ResetClip
        g.ResetClip();

        //Draw rectangles
        g.DrawRectangle(new Pen(Color.Red, 6), rect1);
        g.DrawRectangle(new Pen(Color.Black, 6), rect2);


        g.SetClip(rect2, CombineMode.Exclude);
        g.Clear(Color.White);
        g.ResetClip();
    }
}
}

问题分析

原代码通过裁剪(Clip)操作限制绘制区域,但这只是控制了内容的显示范围,并没有实现**提取局部区域并平移到(0,0)**的核心需求。需要通过离线绘制或屏幕复制的方式实现目标。

解决方案

方案1:针对自定义绘制内容(推荐)

先将所有内容绘制到离线Bitmap中,再截取目标局部区域,最后绘制到(0,0)位置:

private void Form1_Paint(object sender, PaintEventArgs e)
{
    Graphics g = e.Graphics;
    g.Clear(this.BackColor);

    // 定义矩形:rect1为原始大区域,rect2为需要提取的局部区域
    Rectangle rect1 = new Rectangle(0, 0, 500, 500);
    Rectangle rect2 = new Rectangle(0, 100, 500, 200);

    // 1. 将原始内容绘制到离线Bitmap
    using (Bitmap sourceBitmap = new Bitmap(rect1.Width, rect1.Height))
    {
        using (Graphics bitmapGraphics = Graphics.FromImage(sourceBitmap))
        {
            // 绘制原始内容
            bitmapGraphics.DrawString("THIS IS GOING TO BE DELETED", this.Font, Brushes.Black, rect1);
            bitmapGraphics.FillRectangle(Brushes.Magenta, rect2);
            bitmapGraphics.DrawString("TEST MY APP", this.Font, Brushes.White, rect2);
        }

        // 2. 截取rect2区域,绘制到(0,0)位置
        Rectangle destRect = new Rectangle(0, 0, rect2.Width, rect2.Height);
        g.DrawImage(sourceBitmap, destRect, rect2, GraphicsUnit.Pixel);
    }

    // 可选:绘制原始矩形边框用于对比
    g.DrawRectangle(new Pen(Color.Red, 6), rect1);
    g.DrawRectangle(new Pen(Color.Black, 6), rect2);
}

方案2:针对屏幕内容提取

如果需要提取整个屏幕(rect1为屏幕区域)的局部内容,使用CopyFromScreen直接复制屏幕像素:

private void Form1_Paint(object sender, PaintEventArgs e)
{
    Graphics g = e.Graphics;
    g.Clear(this.BackColor);

    // rect1为整个屏幕区域,rect2为屏幕上的局部区域
    Rectangle rect1 = Screen.PrimaryScreen.Bounds;
    Rectangle rect2 = new Rectangle(0, 100, 500, 200);

    // 将rect2区域的屏幕内容复制到当前窗体的(0,0)位置
    g.CopyFromScreen(rect2.Location, Point.Empty, rect2.Size);
}

说明

  • 方案1适用于你自己绘制的内容,能精准控制要提取的区域和内容;
  • 方案2适用于截取屏幕上的现有内容,无需提前绘制。

内容的提问来源于stack exchange,提问作者Xtremexploit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 04:30:57