Есть ли способ преобразовать "рисунок" tkinter в массив байтов? - PullRequest
0 голосов
/ 12 июля 2020

Цель в конце - получить доску (пример: ширина = 200, высота = 20), тогда как каждая единица «ширина / высота» представляет собой пиксель на tkinter GUI. Когда пиксель нажимается, он остается «отмеченным», что позволяет мне рисовать изображения на этой доске. Важно то, что я могу получить информацию о том, какие «пиксели» отмечены / не отмечены (предпочтительно в массиве байтов , например, 11010100, где 1 - это «щелкнуто», а 0 - нет. нажал ").

Термин« пиксели »может сбивать с толку в этом контексте, я не знал, как лучше его описать. У меня есть аналогия (которая немного нелепа, но здесь: "доски для рисования magneti c для детей": щелкните здесь, чтобы увидеть изображение Google ; В данном случае доска - это мой tkinter GUI где я могу рисовать и, в конце концов, после "сохранения" / завершения, я получаю отмеченные пиксели в массиве байтов, предпочтительно слева направо, где каждый столбец читается сверху вниз)

Я пробовал Canvas (который, очевидно) не работает; а также превращение каждого «пикселя» в кнопку (из-за большого разнообразия настроек он идеально подходит), хотя кнопки tkinter, особенно 100+, как правило, загружаются довольно долго.

// EDIT: введите описание изображения здесь самостоятельно ; Чертежная доска должна быть похожей - мне нужна информация о том, какие «пиксели» были отмечены, поэтому я могу поместить их в массив (и, возможно, позже его воссоздать, и т. Д.)

1 Ответ

1 голос
/ 12 июля 2020

Самое простое решение - создать сетку из прямоугольников на холсте. Затем вы можете создать рисунок, задав цвет каждого отдельного прямоугольника. Чтобы получить массив байтов, вы можете перебирать прямоугольники, чтобы получить их цвет.

Вот быстрый и грязный пример. Вы можете рисовать, щелкая и перетаскивая. Когда вы нажимаете кнопку «Распечатать данные», он распечатывает список строк с цифрой «1» везде, где черный квадрат.

Скриншот

Это вывод кнопки:

00000000000000000000
00000000000000000000
00000000000000000000
00000000000000000000
00000001000001000000
00000000000000000000
00000000000000000000
00000000000000000000
00001000000000001000
00000100000000010000
00000011111111100000
00000000000000000000
00000000000000000000
00000000000000000000
00000000000000000000
import tkinter as tk

class DrawableGrid(tk.Frame):
    def __init__(self, parent, width, height, size=5):
        super().__init__(parent, bd=1, relief="sunken")
        self.width = width
        self.height = height
        self.size = size
        canvas_width = width*size
        canvas_height = height*size
        self.canvas = tk.Canvas(self, bd=0, highlightthickness=0, width=canvas_width, height=canvas_height)
        self.canvas.pack(fill="both", expand=True, padx=2, pady=2)

        for row in range(self.height):
            for column in range(self.width):
                x0, y0 = (column * size), (row*size)
                x1, y1 = (x0 + size), (y0 + size)
                self.canvas.create_rectangle(x0, y0, x1, y1,
                                             fill="white", outline="gray",
                                             tags=(self._tag(row, column),"cell" ))
        self.canvas.tag_bind("cell", "<B1-Motion>", self.paint)
        self.canvas.tag_bind("cell", "<1>", self.paint)

    def _tag(self, row, column):
        """Return the tag for a given row and column"""
        tag = f"{row},{column}"
        return tag

    def get_pixels(self):
        row = ""
        for row in range(self.height):
            output = ""
            for column in range(self.width):
                color = self.canvas.itemcget(self._tag(row, column), "fill")
                value = "1" if color == "black" else "0"
                output += value
            print(output)

    def paint(self, event):
        cell = self.canvas.find_closest(event.x, event.y)
        self.canvas.itemconfigure(cell, fill="black")


root = tk.Tk()

canvas = DrawableGrid(root, width=20, height=15, size=10)
b = tk.Button(root, text="Print Data", command=canvas.get_pixels)
b.pack(side="top")
canvas.pack(fill="both", expand=True)
root.mainloop()
...