Direct2D 正在正确呈现。当你给它一个像素坐标比如 (100, 120) 时,它指的是像素元素的左上角,从像素坐标 (100, 120) 到 (101, 121) (包括上/左),右/下是排他的)。由于它是一条水平直线,因此您实际上得到了一个从 (99.5, 119.5) - (300.5, 120.5) 填充的矩形。由于该边缘溢出到相邻像素中,这就是为什么您在“错误”亮度下获得“2 像素宽度”线的原因。您必须考虑像素坐标(没有面积的点)和像素元素(屏幕上的物理点,面积为 1x1,或者当然只有 1)。
如果您想从像素 (100, 120) 到 (300, 120) 绘制一条直线,您应该使用 SemMike 的使用别名渲染的建议(这对直线非常有用!),或者您可以使用一半-像素偏移(因为 strokeWidth=1;对于其他 strokeWidths,按 strokeWidth/2 调整)。从 (100.5, 120.5) - (299.5, 120.5) 以 1.0 的笔划宽度绘制将得到你想要的东西。该笔画围绕您指定的像素坐标延伸,因此您将在像素元素 (100, 120) - (300, 121) 上获得“填充矩形”。再说一次,这是一个排他范围,所以 'y=121' 实际上并没有被填充,x=300 也没有。
如果你想知道为什么像 GDI 这样的东西不会发生这种情况,那是因为它不进行抗锯齿渲染,所以一切总是捕捉到像素元素。如果您想知道为什么 WPF 在使用 Shapes 时不会发生这种情况,那是因为它使用了布局舍入 (UseLayoutRounding) 和像素对齐。Direct2D 不提供这些服务,因为它是一个相对较低级别的 API。