一条线不是由像素组成的。考虑线宽和抗锯齿,修改其轨迹中的像素。使用默认设置绘制一条线并放大图像,如下图所示。很少有像素可以完全 100% 地显示给定颜色。很多像素都变了。
根据您的最终目标,您可以使用the post you linked 中描述的方法计算像素坐标(请注意,保存的图像上的像素可能与屏幕上的像素有一点偏差)。然后使用例如Bresenham's line algorithm 查找中间点的坐标。请注意,一个朴素的 Bresenham 算法会绘制一条 45 度的线,看起来比水平线细得多。在现代屏幕上,一个像素宽的线条几乎是不可见的。
以下是链接代码的可能类似于 Bresenham 的解释:
import numpy as np
import matplotlib.pyplot as plt
def points_in_line(x0, y0, x1, y1):
dx = np.round(np.abs(x1 - x0))
dy = np.round(np.abs(y1 - y0))
steps = int(np.round(max(dx, dy))) + 1
return np.vstack([np.linspace(x0, x1, steps), np.linspace(y0, y1, steps)]).T
fig, ax = plt.subplots()
points, = ax.plot([0, 1, 2, 4, 5, 6, 9], [0, 5, 3, 2, 2, 9, 8], 'b-')
ax.axis([-1, 10, -1, 10])
# Get the x and y data and transform them into pixel coordinates
x, y = points.get_data()
xy_pixels = ax.transData.transform(np.vstack([x, y]).T)
x_pix, y_pix = xy_pixels.T
# find all points in each line
all_pix = [points_in_line(x0, y0, x1, y1) for x0, y0, x1, y1 in zip(x_pix[:-1], y_pix[:-1], x_pix[1:], y_pix[1:])]
all_x_pix, all_y_pix = np.concatenate(all_pix).T
# In matplotlib, 0,0 is the lower left corner, whereas it's usually the upper
# left for most image software, so we'll flip the y-coords...
width, height = fig.canvas.get_width_height()
all_y_pix = height - all_y_pix
print('Coordinates of the lines in pixel coordinates...')
for xp, yp in zip(all_x_pix, all_y_pix):
print(f'{x:0.2f}\t{y:0.2f}')
# save the figure with its current DPI
fig.savefig('test.png', dpi=fig.dpi)