BitWaferMap 2.3.0.22

FastWaferPanel - 高性能晶圆图控件

概述

FastWaferPanel 是一个高性能的 WPF 晶圆图(Wafer Map)自定义控件,专为大规模晶圆测试数据显示而设计。它支持快速渲染、交互式选择和实时数据更新,适用于半导体测试、良率分析等场景。

版本说明

Version 2.3.0.22 (2026年6月30日)

添加 RectMat

渲染流程

Version 2.3.0.16 (2026年6月25日)

Stride 4字节对齐 + IntPtr 单次拷贝 + demo 版本同步修复。

BitImageHost (写入端)

  • Stride 4字节对齐:WPF WriteableBitmap.WritePixels 要求 stride 为 4 的倍数,写入端计算对齐 stride (width × bpp + 3) & ~3,imageSize = stride × height。
  • 智能 padding 处理:SDK 原始数据紧密排列,若 stride 已对齐则整块拷贝;否则逐行补齐 padding 字节后写入 MMF。
  • Push(IntPtr, format) 单次拷贝:SDK 非托管指针 → Buffer.MemoryCopy → MMF 直接指针,跳过 Marshal.Copy + WriteArray 双重拷贝。AcquirePointer 获取 MMF 底层地址直写。
  • MMF 按最大对齐尺寸分配:构造时以 Bgr24 对齐 stride 作为最大帧尺寸分配双缓冲。

BitPipelineHelper (读取端)

  • 读取 HEADER_PIXELFORMAT 自动识别 Bgr24/Gray8,创建对应 WriteableBitmap
  • LastPixelFormat 追踪格式变化,自动重建位图

三条 Push 路径对比

入口 拷贝次数 适用场景 5MP 耗时
Push(Bitmap) GDI+转换 + 2次 需加水印/解码图片 ~100ms
Push(byte[], format) 2次 (SDK→托管→MMF) 已有托管数组 ~30ms
Push(IntPtr, format) 🆕 1次 (SDK→MMF) 直接对接相机SDK ~20ms

发送端示例

// ❌ 旧方式:两次拷贝
Marshal.Copy(frameOut.Image.PixelDataPtr, imageData, 0, dataSize);
streamer.Push(imageData, PixelFormatType.Gray8);

// ✅ 新方式:一次拷贝,三行变一行
streamer.Push(frameOut.Image.PixelDataPtr, PixelFormatType.Gray8);

demo 版本同步

  • ImageStreamer.csSolution.ImageViewer\BitPipelineHelper.cs 同步所有修复

Version 2.3.0.15 (2026年6月24日)

BitImageHost 释放错误修复。

Version 2.3.0.15 (2026年6月23日)

修复双缓冲偏移不一致,新增 Gray8 格式支持,HEADER 增加像素格式字段。

BitImageHost (写入端)

  • 修复双缓冲 BugWriteFrame 改为写入非活跃缓冲区1 - _bufferIndex),与读取端偏移计算一致。旧代码写入活跃缓冲区后交换索引,导致读取端永远读到旧帧。
  • 支持 Gray8Push(byte[] raw, PixelFormatType format) 移除 NotSupportedException,根据格式自动计算 stride(Bgr24→width×3, Gray8→width×1)。
  • HEADER 新增 pixelFormat:offset 24 写入格式标识(0=Bgr24, 1=Gray8),读取端自动识别。

BitPipelineHelper (读取端)

  • 新增 HEADER_PIXELFORMAT 常量:offset 24,与写入端对齐。
  • 自动格式识别:读取 pixelFormat → 创建对应 WriteableBitmapPixelFormats.Bgr24 / PixelFormats.Gray8),bpp 自动推导。
  • 格式变化重建LastPixelFormat 字段追踪,格式变化时自动重建 WriteableBitmap

HEADER 布局(32字节)

Offset:  0      4      8      12     16     20     24       28
      ┌──────┬──────┬──────┬──────┬──────┬──────┬──────┬────────┐
      │Width │Height│Stride│Length│FrmId │BufIdx│PixFmt│ 预留   │
      └──────┴──────┴──────┴──────┴──────┴──────┴──────┴────────┘

pixelFormat 为 int32,可编码 42 亿种格式,后续添加新格式无需扩容。

Version 2.3.0.13 (2026年6月4日)

添加位图处理管道(BitmapPipelineBuilder),支持链式调用对 WriteableBitmap 进行实时处理。

新增类

说明
BitmapPipelineBuilder 链式处理管道构建器
ImageViewer 新增直方图显示、NearestNeighbor 缩放

ImageViewer 新增功能

  • RenderOptions.SetBitmapScalingModeNearestNeighbor:放大时像素不模糊
  • RenderOptions.SetEdgeModeAliased:边缘不抗锯齿
  • 右下角灰度直方图(二值化开启时自动显示)

BitmapPipelineBuilder API

基本用法
// DoBitPipe 返回 BitmapPipelineBuilder,直接链式调用
var pipeline = ImageControl.DoBitPipe("Cam1",
    onConnected: () => { /* 连接成功 */ },
    onDisconnected: () => { /* 连接断开 */ });

pipeline
    .Binarization(50, 200)       // 双阈值二值化(后台线程)
    .Invert()                    // 反色(后台线程)
    .Process(bitmap => { })      // 自定义 UI 线程处理
    .ProcessBuffer((buf, w, h, stride, bpp) => { }); // 自定义后台线程处理
Binarization(双阈值带通滤波)
// 亮度在 [50, 200] → 白色,范围外 → 黑色
pipeline.Binarization(50, 200);

// 运行时实时修改阈值(下一帧生效)
pipeline.SetThresholds(30, 180);

// 开关二值化
pipeline.BinarizationEnabled = false;  // 关闭,显示原始图像
pipeline.BinarizationEnabled = true;   // 打开

// 直方图随 BinarizationEnabled 自动显示/隐藏
自定义处理
方法 线程 签名
Process UI 线程 Action<WriteableBitmap>
ProcessBuffer 后台线程 Action<byte[] buffer, int w, int h, int stride, int bpp>
pipeline
    .ProcessBuffer((buf, w, h, stride, bpp) =>
    {
        // 后台线程,无 WPF 对象,高性能
        for (int y = 0; y < h; y++)
        {
            int row = y * stride;
            for (int x = 0; x < w; x++)
            {
                int i = row + x * bpp;
                // 直接操作 byte[],例如亮度增强
                buf[i] = (byte)Math.Min(255, buf[i] * 1.2);
            }
        }
    })
    .Process(bitmap =>
    {
        // UI 线程,兼容旧 API
        // 可以调用 WriteableBitmapEx 扩展方法
    });
线程模型
每帧 Tick (30ms)
├─ UI 线程 ── ReadArray(读 MMF)→ byte[] buffer
├─ 后台线程 ── Binarization / Invert / ProcessBuffer(操作 byte[])
├─ UI 线程 ── WritePixels(写入处理后的 buffer)
├─ UI 线程 ── Process() 自定义步骤
├─ UI 线程 ── SetImage / 直方图
└─ 防重入:Interlocked 跳过堆积帧
直方图

二值化开启时,右下角自动绘制 256 级灰度直方图,红色线为下限阈值,绿色线为上限阈值。

Version 2.3.0.2 (2026年5月27日)

添加菜单选择范围

Version 2.3.0.0 (2026年5月13日)

RollBack

Version 2.2.0.0 (2026.05.06)

RenderWaferCached()
├─ 位图需要重建?(尺寸/缩放变化)
│   ├─ 是 → 创建新 WriteableBitmap,标记全量重绘
│   └─ 否 → 仅平移,不需要重建
├─ 本帧立即绘制当前位图到 _waferVisual(即使过期,下帧更新)
├─ 捕获参数(Scale, Offset, DieWidth/Height, sorted数组引用等)
└─ Task.Run → 后台线程
    ├─ 遍历可见 Die,计算屏幕像素位置和颜色,填充 byte[]
    ├─ 检查 _renderVersion → 版本过期则丢弃
    └─ Dispatcher.BeginInvoke → UI 线程
        ├─ 再次检查版本号
        ├─ Lock → Marshal.Copy → AddDirtyRect → Unlock
        └─ RequestRender() 触发下帧重绘

平移时位图不需要重建,但内容需要重绘(Die 的屏幕位置变了)。后续可以优化为"滚动位图 + 只绘新露出的边缘"。

Version 2.1.0.9 (2026.04.14)

Version 2.1.0.8 有bug

Version 2.1.0.8 (2026.04.14)

用弱事件

Version 2.1.0.7 (2026.04.14)

RequestRender(高频) ↓ 合并(Dispatcher) PerformRender(单线程) ↓ 循环消费(防丢帧) Render(按需绘制)

Version 2.1.0.6 (2026.04.09)

优化刷新频率是有变化时才刷新

Version 2.1.0 (2026.04.01)

  • 添加进程之前Bitmap图片传送

    使用方式

    发送端
    
    /// <param name="name">通道名称</param>
    /// <param name="width">图片宽度</param>
    /// <param name="height">图片长度</param>
    //public BitImageHost(string name, int width, int height)
    
    var streamer = new BitImageHost("Cam1", 1292, 964);
    
        while (true)
       {
        //byte[] buffer = new byte[stride * height];
        //// 模拟图像(随机)
        //rand.NextBytes(buffer);
        //rand.NextBytes(buffer);
        //streamer.Push(buffer,PixelFormatType.Gray8);        
           streamer.Push((Bitmap)bitmap.Clone());  
           Thread.Sleep(30); // ~30 FPS
       }
    
    接受端
       <Border>
           <ImageViewer x:Name="ImageControl" />
       </Border>
    
      ImageControl.DoBitPipe("Cam1",
          onConnected: () =>
          {
              // 连接成功回调(UI 线程)
              //StatusText.Text = "✅ 已连接 Cam1";
          },
          onDisconnected: () =>
          {
              // 连接断开回调
              //StatusText.Text = "⚠️ Cam1 断开,重连中...";
          });
    

Version 2.0.7 (2026.03.18)

  • 修复 Fps 不显示问题.

  • 添加DIe 状态

    public enum DieStatus
    {
        NONE,
        GOOD,
        BAD,
        EMPTY,
        REF
    }
  • 添加统计功能
    • StatisticsModel: 0表示统计,1表示统计状态,2表示统计Bin
  • 修复加载后Map居中问题
  • 重置BinColor 调整对比度

Version 2.0.0 (2026.02.18)

  • ✨ 初始版本发布

  • 🎨 基础晶圆图渲染功能

  • 🖱️ 鼠标交互(单击、框选、缩放、平移)

  • 📊 60 FPS 流畅渲染

  • 💡 悬停提示功能

  • ⚡ 性能优化:视口裁剪、缓存机制

  • 🎯 新增闪烁提示功能

  • 🔧 添加数学坐标系支持

  • 📝 优化文本渲染,支持动态字体大小

  • 🚀 智能渲染请求系统

  • 🎨 支持自定义 Die 颜色

  • 📋 上下文菜单扩展

  • 🔗 改进数据绑定支持

特性

🚀 高性能渲染

  • 60 FPS 稳定帧率:使用定时器控制渲染频率,确保流畅的视觉体验
  • 智能渲染请求:仅在有变化时请求重绘,避免不必要的性能消耗
  • 视口裁剪:只渲染可见区域内的 Die,大幅提升大数据量下的性能
  • 缓存机制:缓存格式化文本和画笔,减少重复创建开销

🎯 丰富的交互功能

  • 多种选择模式
    • 单击选择单个 Die
    • 框选矩形区域内的多个 Die
    • Ctrl+单击进行多选
  • 鼠标操作
    • 滚轮缩放(支持中心点缩放)
    • 中键拖拽平移视图
    • 右键打开上下文菜单
  • 实时提示
    • 鼠标悬停显示 Die 详细信息
    • 选中数量实时统计

🎨 灵活的显示控制

  • 坐标系统:支持标准坐标系和数学坐标系切换
  • 自定义尺寸:可独立设置 Die 的宽度和高度
  • 动态文本显示:缩放级别足够时自动显示 Die 坐标和 BinCode
  • 闪烁提示:支持指定 Die 的闪烁高亮

🔧 扩展性设计

  • 接口分离:通过 IDieInfo 接口支持自定义数据模型
  • 事件系统
    • DieClicked:单击事件
    • SelectionChanged:选择变化事件
    • HoverChanged:悬停变化事件
    • RequestColorForSelected:请求设置颜色事件
  • 数据绑定:支持与 MVVM 模式无缝集成

快速开始

安装

FastWaferPanel.cs 文件添加到您的 WPF 项目中,并确保引用必要的命名空间:

xml

<Window x:Class="YourNamespace.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:BitWaferMap">
    
    <Grid>
        <local:FastWaferPanel x:Name="waferPanel"
                              Dies="{Binding Dies}"
                              DieWidth="15"
                              DieHeight="15"
                              UseMathCoordinate="False"/>
    </Grid>
</Window>

基本使用

csharp

// 创建数据
var dies = new ObservableCollection<IDieInfo>();
for (int x = 0; x < 50; x++)
{
    for (int y = 0; y < 50; y++)
    {
        dies.Add(new DieInfo
        {
            X = x,
            Y = y,
            BinCode = "PASS",
            Brush = Brushes.LightGreen
        });
    }
}

// 绑定到控件
waferPanel.Dies = dies;

// 居中显示
waferPanel.CenterViewOnDies(dies);

// 适应窗口
waferPanel.FitToWindow(dies);

高级用法

1. 自定义数据模型

实现 IDieInfo 接口来创建自定义数据模型:

csharp

public class CustomDieInfo : IDieInfo
{
    public int X { get; set; }
    public int Y { get; set; }
    public int Row { get; set; }
    public int Col { get; set; }
    public object? Tag { get; set; }
    public Brush Brush { get; set; } = Brushes.LightGray;
    public string BinCode { get; set; } = "N/A";
    
    // 自定义属性
    public double TestValue { get; set; }
    public DateTime TestTime { get; set; }
}

2. 响应选择事件

csharp

waferPanel.SelectionChanged += (s, e) =>
{
    var selected = e.SelectedDies;
    statusBar.Text = $"已选择: {selected.Count} 个 Die";
    
    foreach (var die in selected)
    {
        Console.WriteLine($"Die [{die.X},{die.Y}]: {die.BinCode}");
    }
};

waferPanel.DieClicked += (s, die) =>
{
    MessageBox.Show($"点击了 Die: ({die.X}, {die.Y})");
};

3. 动态更新数据

csharp

// 添加新 Die
if (waferPanel.Dies is ObservableCollection<IDieInfo> collection)
{
    collection.Add(new DieInfo { X = 10, Y = 20, BinCode = "FAIL" });
}

// 更新颜色
waferPanel.ChangeDieColor(5, 5, Brushes.Red);

// 批量更新选中颜色
waferPanel.ApplyColorToSelected(Brushes.Gold);

4. 闪烁提示功能

csharp

// 开始闪烁指定位置的 Die
waferPanel.StartBlink(new[] { (5, 5), (6, 6), (7, 7) });

// 停止闪烁
waferPanel.StopBlink(new[] { (5, 5) });

// 停止所有闪烁
waferPanel.StopAllBlink();

配置选项

属性 类型 说明
Dies IEnumerable<IDieInfo> 晶圆数据源
SelectedDies IEnumerable<IDieInfo> 当前选中的 Die 集合
SelectedDie IDieInfo 当前选中的单个 Die
Mode WaferPanelMode 操作模式(Normal/ExternalAdding/Selecting/Panning)
DieWidth double Die 宽度(像素)
DieHeight double Die 高度(像素)
UseMathCoordinate bool 是否使用数学坐标系(Y轴向上)
Scale double 缩放比例
Offset Point 视图偏移量
IsTrack bool 是否启用视图跟踪
StatisticsModel int 0表示统计,1表示统计状态,2表示统计Bin

性能优化建议

  1. 数据量优化:对于超过 10,000 个 Die 的数据,建议使用虚拟化或分页加载
  2. 渲染优化:当 Die 数量巨大时,可以设置 DieWidth/Height 较小值
  3. 文本显示:只在缩放级别足够时显示文本,避免过多文本渲染
  4. 集合选择:优先使用 ObservableCollection 以便自动响应集合变化

Demo 示例

示例 1:基础晶圆图

csharp

// 创建 100x100 的晶圆图
var dies = new ObservableCollection<IDieInfo>();
var random = new Random();

for (int x = 0; x < 100; x++)
{
    for (int y = 0; y < 100; y++)
    {
        var value = random.NextDouble();
        var binCode = value > 0.9 ? "FAIL" : "PASS";
        var brush = value > 0.9 ? Brushes.Red : Brushes.LightGreen;
        
        dies.Add(new DieInfo
        {
            X = x,
            Y = y,
            BinCode = binCode,
            Brush = brush
        });
    }
}

waferPanel.Dies = dies;

示例 2:实时数据更新

csharp

// 模拟实时测试数据
var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
timer.Tick += (s, e) =>
{
    var random = new Random();
    var x = random.Next(0, 100);
    var y = random.Next(0, 100);
    
    waferPanel.ChangeDieColor(x, y, 
        random.NextDouble() > 0.7 ? Brushes.Red : Brushes.Green);
};
timer.Start();

示例 3:良率分析

csharp

waferPanel.SelectionChanged += (s, e) =>
{
    var selected = e.SelectedDies;
    var failCount = selected.Count(d => d.BinCode == "FAIL");
    
    analysisText.Text = $"选中区域: {selected.Count} 个 Die\n" +
                       $"不良数: {failCount}\n" +
                       $"良率: {(1 - (double)failCount/selected.Count):P2}";
};

示例 4:自定义上下文菜单

csharp

var contextMenu = new ContextMenu();

var menuAnalyze = new MenuItem { Header = "分析选中区域" };
menuAnalyze.Click += (s, e) => AnalyzeSelectedRegion();

var menuExport = new MenuItem { Header = "导出数据" };
menuExport.Click += (s, e) => ExportSelectedData();

contextMenu.Items.Add(menuAnalyze);
contextMenu.Items.Add(menuExport);

waferPanel.ContextMenu = contextMenu;

常见问题

贡献指南

欢迎贡献代码、报告问题或提出新功能建议。请遵循以下步骤:

  1. Fork 项目
  2. 创建功能分支 (git checkout -b feature/AmazingFeature)
  3. 提交更改 (git commit -m 'Add some AmazingFeature')
  4. 推送到分支 (git push origin feature/AmazingFeature)
  5. 创建 Pull Request

许可证

本项目采用 MIT 许可证 - 详见 LICENSE 文件

联系方式

  • 作者:[cq.li]
  • 邮箱:[lcq186@qq.com]
  • 项目地址:[]

FastWaferPanel - 为半导体测试行业提供高性能、易扩展的晶圆图显示解决方案

No packages depend on BitWaferMap.

用于显示和操作晶圆图(Wafer Map)

.NET Framework 4.8

Version Downloads Last updated
2.3.0.22 8 06/30/2026
2.3.0.21 12 06/26/2026
2.3.0.20 10 06/26/2026
2.3.0.19 10 06/24/2026
2.3.0.18 7 06/24/2026
2.3.0.17 7 06/24/2026
2.3.0.16 10 06/24/2026
2.3.0.15 6 06/24/2026
2.3.0.14 9 06/16/2026
2.3.0.13 19 06/04/2026
2.3.0.12 9 06/04/2026
2.3.0.11 11 06/04/2026
2.3.0.10 9 06/04/2026
2.3.0.9 10 06/04/2026
2.3.0.8 9 06/03/2026
2.3.0.7 10 06/03/2026
2.3.0.6 10 05/28/2026
2.3.0.5 11 05/28/2026
2.3.0.4 12 05/28/2026
2.3.0.3 10 05/28/2026
2.3.0.2 13 05/27/2026
2.3.0.1 15 05/13/2026
2.3.0 12 05/13/2026
2.2.0 11 05/06/2026
2.1.2.9 10 04/28/2026
2.1.2.8 11 04/28/2026
2.1.2.7 11 04/27/2026
2.1.2.6 10 04/27/2026
2.1.2.5 11 04/27/2026
2.1.2.4 11 04/27/2026
2.1.2.1 10 04/26/2026
2.1.2 13 04/25/2026
2.1.1 14 04/17/2026
2.1.0.9 10 04/14/2026
2.1.0.8 9 04/14/2026
2.1.0.7 11 04/14/2026
2.1.0.6 12 04/09/2026
2.1.0.5 12 04/08/2026
2.1.0.4 13 04/08/2026
2.1.0.3 11 04/08/2026
2.1.0.2 11 04/08/2026
2.1.0.1 10 04/08/2026
2.1.0 15 04/01/2026
2.0.0.8 14 03/27/2026
2.0.0.7 16 03/17/2026
2.0.0.6 19 03/11/2026
2.0.0.5 15 03/11/2026
2.0.0.4 18 03/11/2026
2.0.0.3 13 03/11/2026
2.0.0.2 21 03/02/2026
2.0.0.1 17 03/02/2026
2.0.0 25 02/18/2026
1.0.7.4 23 02/02/2026
1.0.7.3 21 01/06/2026
1.0.7.1 22 12/31/2025
1.0.7 22 12/31/2025
1.0.6.13 7 07/03/2026
1.0.6.12 6 07/03/2026
1.0.6.11 9 06/15/2026
1.0.6.10 13 05/19/2026
1.0.6.9 13 05/18/2026
1.0.6.8 12 05/18/2026
1.0.6.7 38 12/22/2025
1.0.6.4 29 12/22/2025
1.0.6.3 30 12/18/2025
1.0.6.2 24 12/18/2025
1.0.6.1 22 12/18/2025
1.0.6 20 12/18/2025
1.0.5 22 12/18/2025