自动交叉模式

时间:2017-12-14 12:21:29

标签: python matplotlib tkinter

我正在尝试使用python创建一个十字绣图案,如附图所示。

到目前为止,我只是拥有像素化图像。我可以在excel中导入它并手动添加网格和颜色等。但是如何在Python中“轻松”自动执行此操作?我可以使用任何普通的数字绘图功能(pyplot),还是应该查看tkinter?

我可以很好地在python中创建用于工程目的的脚本,但对GUI内容来说是全新的。

理想情况下,我的输出将是向量pdf

Cross stitch pattern

from scipy import misc
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.ticker as plticker

arr = misc.imread('Fox_drawing_pixelized.png', mode= 'RGBA') # 640x480x3 array

fig = plt.figure()
imgplot = plt.imshow(arr) # RGBA
ax = plt.gca()
ax.grid(True)
ax.grid(b=True, which='major', color='b', linestyle='-')
plt.minorticks_on()
loc = plticker.MultipleLocator(base=1)
ax.xaxis.set_minor_locator(loc)
ax.yaxis.set_minor_locator(loc)
ax.grid(b=True, which='minor', color='k', linestyle='-',linewidth=.3)
fig.savefig("foo.pdf", bbox_inches='tight')
  • 如何将网格线设置为0.5而不是单位(从中间到每个像素)?

  • 如何在每个像素中绘制文字,我已经将图像放在数组中,如何在顶部绘制数字?

1 个答案:

答案 0 :(得分:0)

  • 要移动网格线,您只需更改刻度线位置:
    ax.set_xticks(np.arange(-0.5, arr.shape[1], 5))
    从第一个像素的边界开始,每5个像素放一个主刻度 ax.set_xticks(np.arange(-0.5, arr.shape[1], 1), minor=True)
    做同样的事情,但每个像素的小刻度。然后使用arr.shape[0]为y做同样的事情。

  • 要添加文字,您只需使用ax.text(x, y, 'text')即可。我使用字典来匹配文本的颜色(十六进制格式,因为rgb列表不能是字典键)。你需要注意的是(i,j)矩阵索引对应于(y,x)坐标。

以下是完整代码:

from scipy import misc
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.ticker as plticker
from matplotlib.colors import to_hex

arr = misc.imread('image.png', mode= 'RGB') # array
# adapt figure size to the image size.
fig = plt.figure(figsize=(0.2*arr.shape[1], 0.2*arr.shape[0]))
imgplot = plt.imshow(arr) # RGB
ax = plt.gca()
ax.grid(True)
ax.grid(b=True, which='major', color='b', linestyle='-')
plt.minorticks_on()
ax.grid(b=True, which='minor', color='k', linestyle='-',linewidth=.3)

# put a major gridline every 5 pixels
ax.set_xticks(np.arange(-0.5, arr.shape[1], 5))
ax.set_yticks(np.arange(-0.5, arr.shape[0], 5))
# set ticks label
ax.set_xticklabels(np.arange(0, arr.shape[1], 5))
ax.set_yticklabels(np.arange(0, arr.shape[0], 5))
# put a minor gridline every pixel
ax.set_xticks(np.arange(-0.5, arr.shape[1], 1), minor=True)
ax.set_yticks(np.arange(-0.5, arr.shape[0], 1), minor=True)
fig.tight_layout(pad=0)  # reduce space around image

# display text
colors_to_text = {'#000000': 'B', '#ffffff': 'W', '#f58a35': 'O', '#bcbbbb': 'G'}

for i in range(arr.shape[0]):
    for j in range(arr.shape[1]):
        # get the text corresponding to the pixel color
        txt = colors_to_text.get(to_hex(arr[i,j]/255), '')
        # display text (x, y are inverted compared to the i, j indexes of the matrix)
        ax.text(j, i, txt, color='#888888', horizontalalignment='center', 
                verticalalignment='center', fontsize=7)

fig.savefig("foo.pdf", bbox_inches='tight')

图片pixelated image给了我这样的结果: result

相关问题