首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C# GDI+ 繪圖出現黑色邊框:畫筆寬度導致矩形填滿畫布

     編輯:程式設計綜合問答

問題現象

使用 Graphics.DrawRectangle 繪製白色背景矩形時,將 Bitmap 尺寸從 400×200 改為 1000×500 後,出現巨大黑色邊框遮蓋畫布。

錯誤程式碼

// 錯誤:用 400 像素寬的畫筆畫邊框
g.DrawRectangle(new Pen(Color.White, 400), 0, 0, img.Width, img.Height);

根因分析

  • Pen 的第二個參數是**畫筆寬度**,單位為像素
  • new Pen(Color.White, 400) 創建了一支**寬度 400 像素**的畫筆
  • DrawRectangle 以矩形**中心線**為基準,向內外各延伸 200 像素
  • 畫布 400×200 時:畫筆剛好覆蓋整個畫布,視覺上變白
  • 畫布 1000×500 時:畫筆只覆蓋中心 400×400 區域,外圍露出預設黑色背景

正確做法:用填充而非描邊

// ✅ 正確:填充整個矩形區域
g.FillRectangle(new SolidBrush(Color.White), 0, 0, img.Width, img.Height);

// 或清空畫布
g.Clear(Color.White);  // 最簡單、效能最好

GDI+ 繪圖核心概念對照

完整修正範例

public MemoryStream DrawChart() {
    using (Bitmap img = new Bitmap(1000, 500))
    using (Graphics g = Graphics.FromImage(img)) {
        // 1. 高品質設定
        g.SmoothingMode = SmoothingMode.AntiAlias;
        g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
        g.InterpolationMode = InterpolationMode.HighQualityBicubic;
        
        // 2. 正確清空背景
        g.Clear(Color.White);  // 替代錯誤的 DrawRectangle
        
        // 3. 繪製座標軸、曲線...
        using (Pen axisPen = new Pen(Color.Black, 2))
        using (Pen curvePen = new Pen(Color.Blue, 1.5f))
        using (SolidBrush pointBrush = new SolidBrush(Color.Red)) {
            // 座標軸
            g.DrawLine(axisPen, 100, 450, 900, 450); // X軸
            g.DrawLine(axisPen, 100, 450, 100, 50);  // Y軸
            
            // 曲線繪製邏輯...
        }
        
        // 4. 輸出
        MemoryStream ms = new MemoryStream();
        img.Save(ms, ImageFormat.Png);  // PNG 無損,比 JPEG 適合圖表
        return ms;
    }
}

資源管理最佳實踐

  • ✅ 所有 IDisposable (Pen, Brush, Font, Graphics, Bitmap, MemoryStream) 用 using 包裹
  • ✅ 避免在循環中創建筆刷,提取到循環外復用
  • ✅ 大圖片考慮 Bitmap(..., PixelFormat.Format32bppPArgb) 效能更好

延伸:座標系轉換輔助類

public class ChartTransform {
    public RectangleF DataRect { get; set; }   // 數據範圍
    public RectangleF DrawRect { get; set; }   // 繪圖區域 (留白邊距)
    
    public PointF Transform(float x, float y) {
        float scaleX = DrawRect.Width / DataRect.Width;
        float scaleY = DrawRect.Height / DataRect.Height;
        return new PointF(
            DrawRect.Left + (x - DataRect.Left) * scaleX,
            DrawRect.Bottom - (y - DataRect.Bottom) * scaleY  // Y軸翻轉
        );
    }
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
操作方法用途參數含義
描邊DrawRectangle畫邊框Pen 寬度 = 邊框粗細
填充FillRectangle填滿區域Brush = 填充樣式
清空Clear整圖填色Color = 背景色