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

Windows Forms中使用PaintEvent导致绘制伪影问题排查

图片特定区域高亮功能的异常绘制伪影问题

我正在实现图片特定区域高亮功能,逻辑为将图片除目标区域外的部分变暗,目标区域的位置和尺寸通过参数传入。已完成概念验证(POC),功能可运行,但出现无法消除的异常绘制伪影(图片左侧非预期异常区域)。

设计器代码

partial class cComponentWindow
{
    /// <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.btnOkay = new System.Windows.Forms.Button();
        this.StaticLabel = new System.Windows.Forms.Label();
        this.DynamicLabel = new System.Windows.Forms.Label();
        this.PCBPictureBox = new System.Windows.Forms.PictureBox();
        ((System.ComponentModel.ISupportInitialize)(this.PCBPictureBox)).BeginInit();
        this.SuspendLayout();
        // 
        // btnOkay
        // 
        this.btnOkay.Location = new System.Drawing.Point(12, 480);
        this.btnOkay.Name = "btnOkay";
        this.btnOkay.Size = new System.Drawing.Size(820, 23);
        this.btnOkay.TabIndex = 1;
        this.btnOkay.Text = "Okay";
        this.btnOkay.UseVisualStyleBackColor = true;
        this.btnOkay.Click += new System.EventHandler(this.btnOkay_Click);
        // 
        // StaticLabel
        // 
        this.StaticLabel.AutoSize = true;
        this.StaticLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
        this.StaticLabel.Location = new System.Drawing.Point(8, 2);
        this.StaticLabel.Name = "StaticLabel";
        this.StaticLabel.Size = new System.Drawing.Size(130, 20);
        this.StaticLabel.TabIndex = 3;
        this.StaticLabel.Text = "Some Static Text";
        // 
        // DynamicLabel
        // 
        this.DynamicLabel.AutoSize = true;
        this.DynamicLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
        this.DynamicLabel.Location = new System.Drawing.Point(12, 25);
        this.DynamicLabel.Name = "DynamicLabel";
        this.DynamicLabel.Size = new System.Drawing.Size(104, 20);
        this.DynamicLabel.TabIndex = 2;
        this.DynamicLabel.Text = "Dynamic Text";
        // 
        // PCBPictureBox
        // 
        this.PCBPictureBox.InitialImage = null;
        this.PCBPictureBox.Location = new System.Drawing.Point(25, 25);
        this.PCBPictureBox.Name = "PCBPictureBox";
        this.PCBPictureBox.Size = new System.Drawing.Size(790, 450);
        this.PCBPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
        this.PCBPictureBox.TabIndex = 4;
        this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form_Paint);
        this.PCBPictureBox.TabStop = false;
        // 
        // cComponentWindow
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(844, 511);
        this.Controls.Add(this.DynamicLabel);
        this.Controls.Add(this.StaticLabel);
        this.Controls.Add(this.btnOkay);
        this.Controls.Add(this.PCBPictureBox);
        this.Name = "cComponentWindow";
        this.Text = "Title";
        this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form_Paint); // I also tried commenting this auto generated one out. That didn't change anything.
        ((System.ComponentModel.ISupportInitialize)(this.PCBPictureBox)).EndInit();
        this.ResumeLayout(false);
        this.PerformLayout();
    }

    #endregion
    private System.Windows.Forms.Button btnOkay;
    private System.Windows.Forms.PictureBox PCBPictureBox;
    private System.Windows.Forms.Label StaticLabel;
    private System.Windows.Forms.Label DynamicLabel;
}

业务逻辑代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
public partial class cComponentWindow : Form
{
    // Variables:
    private UInt16 SizeX;
    private UInt16 SizeY;
    private UInt16 OffsetX;
    private UInt16 OffsetY;
    private bool[,] Matrix;
    private PaintEventArgs e;
    private Pen DarkPen = new Pen(Color.FromArgb(127, 0, 0, 0));

    // Methodes:
    public cComponentWindow(UInt16 OffsetX, UInt16 OffsetY, UInt16 SizeX, UInt16 SizeY, String CHK, Image Picture)
    {
        InitializeComponent();
        this.OffsetX = OffsetX;
        this.OffsetY = OffsetY;
        this.SizeX = SizeX;
        this.SizeY = SizeY;
        this.DynamicLabel.Text = CHK;
        this.PCBPictureBox.Image = Picture;
        this.Matrix = new bool[this.SizeX, this.SizeY];
    }

    private void btnOkay_Click(object sender, EventArgs e)
    {
        this.DialogResult = DialogResult.OK;
        Close();
    }

    private void Form_Paint(object sender, PaintEventArgs e)
    {
        this.e = e;
        this.Draw();
    }

    public void Highlight(UInt16 OffsetX, UInt16 OffsetY, UInt16 SizeX, UInt16 SizeY)
    {
        for (UInt16 x = 0; x < SizeX; x++)
        {
            for (UInt16 y = 0; y < SizeY; y++)
            {
                this.Matrix[OffsetX + x, OffsetY + y] = true;
            }
        }
    }

    private void Draw() // OG time: 2m20s after some optimisations 0.5s (-99.6%)
    {
        //e.Graphics.FillRectangle(new SolidBrush(Color.Green), 0, 27, 790, 395 + 27);
        // Go through the entire matrix.
        for (UInt16 y = 0; y < this.SizeY; y++)
        {
            UInt16 StartBlock = 0;
            bool PreviousValue = false;
            for (UInt16 x = 0; x < this.SizeX; x++)
            {
                bool CurrentValue = Matrix[x, y];
                if (CurrentValue && !PreviousValue)
                {   // Draw the line to a highlight.
                    e.Graphics.DrawLine(DarkPen, this.OffsetX + StartBlock, this.OffsetY + y, this.OffsetX + x - 1, this.OffsetY + y);
                }
                if (!CurrentValue && this.SizeX - 1 == x)
                {   // Draw the line to the edge of the screen.
                   e.Graphics.DrawLine(DarkPen, this.OffsetX + StartBlock, this.OffsetY + y, this.OffsetX + x, this.OffsetY + y);
                }
                if (PreviousValue && !CurrentValue)
                {   // Mark the start of the line.
                    StartBlock = x;
                }
                PreviousValue = CurrentValue;
            }
        }
    }
}

调用代码

// x Offset relative to top left of the picturebox, y Offset relative to top left of the picturebox, width of the photo <= picturebox width, height of the photo <= picturebox height.
cComponentWindow Window = new cComponentWindow(0, 27, 790, 395, "Text to be dynamically displayed", global::G458.Properties.Resources.Test_Picture);
// x Offset relative to top left of the darken area, y Offset relative to top left of the darken area, width of the highlight <= darken area width, height of the highlight <= darken area height.
Window.Highlight(10, 10, 250, 150);
Window.Highlight(500, 300, 100, 50);
Window.ShowDialog();

已尝试的排查方法

  • 调整变暗区域的位置/尺寸:伪影形状改变但仍存在
  • 将PaintEvent绑定到窗口而非PictureBox:结果完全相同
  • 仅保留PictureBox的PaintEvent,注释窗口的PaintEvent:结果无变化

我不清楚如何修复该问题,希望得到解决方案或建议。

编辑:后续在添加功能和调整代码的过程中,问题意外解决,但不确定具体修复原因。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 10:04:49