🎨 Как ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ ASCII-Π³Ρ€Π°Ρ„ΠΈΠΊΠΈ Π½Π° Python

Энтузиасты Π΄Π΅Π»Π°ΡŽΡ‚ ASCII-Ρ€Π΅ΠΌΠ΅ΠΉΠΊΠΈ Β«Π—Π²Π΅Π·Π΄Π½Ρ‹Ρ… Π²ΠΎΠΉΠ½Β» ΠΈ Ρ€ΠΎΠ»Π΅Π²Ρ‹Π΅ ASCII-ΠΈΠ³Ρ€Ρ‹. А ΠΌΡ‹ напишСм GUI-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ для ΠΊΠΎΠ½Π²Π΅Ρ€Ρ‚Π°Ρ†ΠΈΠΈ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ Π² ΠΎΠ»Π΄ΡΠΊΡƒΠ»ΡŒΠ½ΡƒΡŽ ASCII-Π³Ρ€Π°Ρ„ΠΈΠΊΡƒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Python ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Pillow.

Π’Π΅Ρ…Π½ΠΈΠΊΠ° создания ΠΈΠ»Π»ΡŽΡΡ‚Ρ€Π°Ρ†ΠΈΠΉ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΏΠ΅Ρ‡Π°Ρ‚Π½Ρ‹Ρ… символов появилась Π·Π°Π΄ΠΎΠ»Π³ΠΎ Π΄ΠΎ появлСния ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€ΠΎΠ² – Π² ΠΊΠΎΠ½Ρ†Π΅ 19-Π³ΠΎ Π²Π΅ΠΊΠ°. ΠŸΠ΅Ρ€Π²Ρ‹Π΅ тСкстовыС изобраТСния создавали Π½Π° ΠΏΠ΅Ρ‡Π°Ρ‚Π½Ρ‹Ρ… ΠΌΠ°ΡˆΠΈΠ½ΠΊΠ°Ρ… ΠΈ ΠΏΡƒΠ±Π»ΠΈΠΊΠΎΠ²Π°Π»ΠΈ Π² руководствах для ΠΌΠ°ΡˆΠΈΠ½ΠΈΡΡ‚ΠΎΠΊ Π² качСствС ΡƒΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠΉ:

Арт-ΠΏΠ΅Ρ‡Π°Ρ‚ΡŒ ΡΡ‡ΠΈΡ‚Π°Π»Π°ΡΡŒ Ρ…ΠΎΡ€ΠΎΡˆΠΈΠΌ ΡƒΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ΠΌ для развития Π½Π°Π²Ρ‹ΠΊΠΎΠ²

ΠŸΡ€ΠΈ создании ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ Π½Π° ΠΏΠ΅Ρ‡Π°Ρ‚Π½ΠΎΠΉ машинкС ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π°ΡΠΏΠΎΠ»Π°Π³Π°Ρ‚ΡŒ символы внахлСст – благодаря этому изобраТСния выглядят ΠΏΠΎΡ‡Ρ‚ΠΈ ΠΊΠ°ΠΊ типографскиС ΠΈΠ»Π»ΡŽΡΡ‚Ρ€Π°Ρ†ΠΈΠΈ. Автором ΠΏΠ΅Ρ€Π²ΠΎΠΉ ΠΏΠΎΠ»Π½ΠΎΡ†Π΅Π½Π½ΠΎΠΉ тСкстовой ΠΈΠ»Π»ΡŽΡΡ‚Ρ€Π°Ρ†ΠΈΠΈ считаСтся ΠΌΠ°ΡˆΠΈΠ½ΠΈΡΡ‚ΠΊΠ° Π€Π»ΠΎΡ€Π° Бтэйси. Π­Ρ‚Π° ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠ° Π±Ρ‹Π»Π° ΠΎΠΏΡƒΠ±Π»ΠΈΠΊΠΎΠ²Π°Π½Π° Π² «ЀонСтичСском ΠΆΡƒΡ€Π½Π°Π»Π΅Β» Π² октябрС 1898 Π³:

Π˜Π»Π»ΡŽΡΡ‚Ρ€Π°Ρ†ΠΈΡ составлСна ΠΈΠ· мноТСства скобок, дСфисов, Π·Π²Π΅Π·Π΄ΠΎΡ‡Π΅ΠΊ, Ρ‚ΠΎΡ‡Π΅ΠΊ ΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… прописных Π±ΡƒΠΊΠ²

Π‘ появлСниСм ΠΏΠ΅Ρ€Π²Ρ‹Ρ… ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€ΠΎΠ² тСкстовый Π°Ρ€Ρ‚ сразу Π²Ρ‹ΡˆΠ΅Π» Π½Π° Π½ΠΎΠ²Ρ‹ΠΉ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ: Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΠΏΠ΅Ρ‡Π°Ρ‚Π½ΡƒΡŽ Π³Ρ€Π°Ρ„ΠΈΠΊΡƒ ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎ. ΠŸΠ΅Ρ€Π²Ρ‹Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ ASCII-Π°Ρ€Ρ‚Π° ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡ‚ΠΈ Π² ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π½Ρ‹Ρ… ΠΆΡƒΡ€Π½Π°Π»Π°Ρ… ΠΈ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ 1960-Ρ… Π³ΠΎΠ΄ΠΎΠ², Ρ‡ΡƒΡ‚ΡŒ ΠΏΠΎΠ·ΠΆΠ΅ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ASCII стали ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ ΡΠ»ΠΎΠΆΠ½ΡƒΡŽ Π³Ρ€Π°Ρ„ΠΈΠΊΡƒ, Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΡŽ ΠΈ ΠΈΠ³Ρ€Ρ‹.

ASCII-ΠΏΠΎΡ€Ρ‚Ρ€Π΅Ρ‚ ΠœΠΎΠ½Ρ‹ Π›ΠΈΠ·Ρ‹ Π² Ρ„ΠΈΠ»ΡŒΠΌΠ΅ Β«Π‘Π»ΡƒΠΆΠ΅Π±Π½Ρ‹ΠΉ Ρ€ΠΎΠΌΠ°Π½Β» 1977

ΠšΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π½Π°Ρ Π³Ρ€Π°Ρ„ΠΈΠΊΠ° ΠΏΡ€ΠΎΡˆΠ»Π° Π΄ΠΎΠ»Π³ΠΈΠΉ ΠΏΡƒΡ‚ΡŒ ΠΎΡ‚ простых тСкстовых Π°Ρ€Ρ‚ΠΎΠ² Π΄ΠΎ фоторСалистичных ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ, сгСнСрированных с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ИИ. Но ASCII-Π°Ρ€Ρ‚ Π½ΠΈΠΊΡƒΠ΄Π° Π½Π΅ дСлся ΠΈ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Π΅Ρ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΏΠΎΠΏΡƒΠ»ΡΡ€Π½ΠΎΡΡ‚ΡŒΡŽ: энтузиасты ΡΠΎΠ·Π΄Π°ΡŽΡ‚ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ для Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ ΠΈ рСдактирования тСкстовой Π³Ρ€Π°Ρ„ΠΈΠΊΠΈ/Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ, Π΄Π΅Π»Π°ΡŽΡ‚ ASCII-вСрсии Β«Π—Π²Π΅Π·Π΄Π½Ρ‹Ρ… Π²ΠΎΠΉΠ½Β» ΠΈ ΠΏΠΎΡ‚Ρ€ΡΡΠ°ΡŽΡ‰ΠΈΠ΅ ΠΈΠ³Ρ€Ρ‹.

Как ΠΊΠΎΠ½Π²Π΅Ρ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Π² ASCII-Π°Ρ€Ρ‚ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Python

ΠœΡ‹ напишСм ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ для Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ ASCII-Π³Ρ€Π°Ρ„ΠΈΠΊΠΈ Π½Π° Python. Π­Ρ‚ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅:

  • ΠžΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ изобраТСния Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π°Ρ… jpg, png ΠΈ bmp.
  • Π˜ΠΌΠ΅Π΅Ρ‚ GUI (интСрфСйс) Π½Π° Tkinter.
  • БохраняСт Π³ΠΎΡ‚ΠΎΠ²Ρ‹ΠΉ ASCII-Π°Ρ€Ρ‚ Π² тСкстовом Ρ„Π°ΠΉΠ»Π΅ с Ρ‚Π΅ΠΌ ΠΆΠ΅ ΠΈΠΌΠ΅Π½Π΅ΠΌ, Ρ‡Ρ‚ΠΎ ΠΈ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ исходного изобраТСния.

Π£ прилоТСния Π΅ΡΡ‚ΡŒ ΠΎΠ΄Π½Π° внСшняя Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ – Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Pillow, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ pip install pillow.

Π’ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ΅ Pillow Π΅ΡΡ‚ΡŒ мноТСство инструмСнтов для слоТных манипуляций с изобраТСниями. Π’ нашСм случаС Pillow ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ‚:

  • Π£ΠΌΠ΅Π½ΡŒΡˆΠΈΡ‚ΡŒ исходноС ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Π΄ΠΎ ΠΆΠ΅Π»Π°Π΅ΠΌΠΎΠΉ ΡˆΠΈΡ€ΠΈΠ½Ρ‹, ΠΈ ΠΏΡ€ΠΎΠΏΠΎΡ€Ρ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎ ΡΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ высоту.
  • ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Π² ΠΎΡ‚Ρ‚Π΅Π½ΠΊΠΈ сСрого.

Π˜Π½Ρ‚Π΅Ρ€Ρ„Π΅ΠΉΡ

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ основного ΠΎΠΊΠ½Π° прилоТСния

Π’ Π½Π°Ρ‡Π°Π»Π΅ ΠΊΠΎΠ΄Π° ΠΌΡ‹ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅ΠΌ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ ΠΌΠΎΠ΄ΡƒΠ»ΠΈ ΠΈ создаСм класс ImageToASCIIConverter. Π­Ρ‚ΠΎΡ‚ класс Π±ΡƒΠ΄Π΅Ρ‚ основным ΠΎΠΊΠ½ΠΎΠΌ нашСго прилоТСния. Π’ конструкторС __init__ ΠΌΡ‹ опрСдСляСм Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ ΠΎΠΊΠ½Π° ΠΈ Π΅Π³ΠΎ ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π° экранС, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ для хранСния ссылок Π½Π° изобраТСния:

class ImageToASCIIConverter(tk.Tk):
    def __init__(self):
        super().__init__()
        screen_width = self.winfo_screenwidth()
        screen_height = self.winfo_screenheight()
        # ВычисляСм ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ для размСщСния ΠΎΠΊΠ½Π° ΠΏΠΎ Ρ†Π΅Π½Ρ‚Ρ€Ρƒ
        x = (screen_width // 2) - (700 // 2)  # Π¨ΠΈΡ€ΠΈΠ½Π° ΠΎΠΊΠ½Π° - 700 пиксСлСй
        y = (screen_height // 2) - (600 // 2)  # Высота ΠΎΠΊΠ½Π° - 600 пиксСлСй
        self.geometry(f"700x600+{x}+{y}")
        self.title("ΠšΠΎΠ½Π²Π΅Ρ€Ρ‚Π°Ρ†ΠΈΡ изобраТСния Π² ASCII-Π°Ρ€Ρ‚")
        self.original_image = None
        self.ascii_image = None
        self.images = {}
        self.create_widgets()

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π²ΠΈΠ΄ΠΆΠ΅Ρ‚ΠΎΠ²

ΠœΠ΅Ρ‚ΠΎΠ΄ create_widgets ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ Π·Π° созданиС всСх Π²ΠΈΠ΄ΠΆΠ΅Ρ‚ΠΎΠ² (ΠΊΠ½ΠΎΠΏΠΎΠΊ, тСкстовых ΠΏΠΎΠ»Π΅ΠΉ, холста для отобраТСния ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ) Π² ΠΎΠΊΠ½Π΅ прилоТСния. Π—Π΄Π΅ΡΡŒ ΠΌΡ‹ создаСм Ρ„Ρ€Π΅ΠΉΠΌΡ‹ для размСщСния Π²ΠΈΠ΄ΠΆΠ΅Ρ‚ΠΎΠ², холст для отобраТСния исходного изобраТСния, тСкстовоС ΠΏΠΎΠ»Π΅ для отобраТСния ASCII-Π°Ρ€Ρ‚Π°, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΊΠ½ΠΎΠΏΠΊΠΈ для Π²Ρ‹Π±ΠΎΡ€Π° изобраТСния, прСобразования Π΅Π³ΠΎ Π² ASCII-Π°Ρ€Ρ‚ ΠΈ сохранСния Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°:

    def create_widgets(self):
        # Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Ρ„Ρ€Π΅ΠΉΠΌΠ° ΠΈ элСмСнтов интСрфСйса
        main_frame = tk.Frame(self)
        main_frame.pack(fill="both", expand=True, padx=10, pady=10)

        # Π˜ΡΡ…ΠΎΠ΄Π½ΠΎΠ΅ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅
        original_image_frame = tk.Frame(main_frame)
        original_image_frame.pack(side="left", padx=10)

        # ΠŸΠ»Π΅ΠΉΡΡ…ΠΎΠ»Π΄Π΅Ρ€
        self.canvas = tk.Canvas(original_image_frame, width=300, height=300)
        self.canvas.pack()
        self.canvas.create_rectangle(0, 0, 300, 300, fill="light blue", outline="")
        self.canvas.create_text(150, 150, text="Π’Ρ‹Π±Π΅Ρ€ΠΈΡ‚Π΅ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅", font=("Verdana", 16))

        # ВСкстовоС ΠΏΠΎΠ»Π΅ для Π²Ρ‹Π²ΠΎΠ΄Π° ASCII-Π°Ρ€Ρ‚Π°
        ascii_text_frame = tk.Frame(main_frame)
        ascii_text_frame.pack(side="right", padx=10)
        self.ascii_text = tk.Text(ascii_text_frame, width=100, height=50, font=("Courier", 4), state="disabled")
        self.ascii_text.pack(side="top", pady=10)

        # Кнопки
        button_frame = tk.Frame(self)
        button_frame.pack(pady=10)
        choose_image_button = tk.Button(button_frame, text="Π’Ρ‹Π±Ρ€Π°Ρ‚ΡŒ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅", command=self.choose_image)
        choose_image_button.pack(side="left", padx=5)
        self.convert_button = tk.Button(button_frame, text="ΠšΠΎΠ½Π²Π΅Ρ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ", command=self.display_ascii_art, state="disabled")
        self.convert_button.pack(side="left", padx=5)
        self.save_button = tk.Button(button_frame, text="Π‘ΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ", command=self.save_ascii_art, state="disabled")
        self.save_button.pack(side="left", padx=5)

Основная Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ

Π’Ρ‹Π±ΠΎΡ€ изобраТСния

ΠœΠ΅Ρ‚ΠΎΠ΄ choose_image ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ΅ ΠΎΠΊΠ½ΠΎ для Π²Ρ‹Π±ΠΎΡ€Π° Ρ„Π°ΠΉΠ»Π° изобраТСния. ВсС доступныС для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Ρ‹ Ρ„Π°ΠΉΠ»ΠΎΠ² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Ρ‹ Π² image_exts, ΠΏΡ€ΠΈ ΠΆΠ΅Π»Π°Π½ΠΈΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹Π±Ρ€Π°Ρ‚ΡŒ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π°. Если ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π²Ρ‹Π±ΠΈΡ€Π°Π΅Ρ‚ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅, ΠΎΠ½ΠΎ отобраТаСтся Π½Π° холстС, Π° ΠΊΠ½ΠΎΠΏΠΊΠ° ΠšΠΎΠ½Π²Π΅Ρ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ становится доступной для наТатия:

    def choose_image(self): #Π’ΠΈΠΏΡ‹ Ρ„Π°ΠΉΠ»ΠΎΠ², Π²ΠΈΠ΄ΠΈΠΌΡ‹Π΅ Π² Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠΌ ΠΎΠΊΠ½Π΅
        image_exts = r"*.jpg *.jpeg *.png *.bmp"
        image_filetypes = [
            ("Π˜Π·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΡ", image_exts),
            ("JPEG", "*.jpg;*.jpeg"),
            ("PNG", "*.png"),
            ("BMP", "*.bmp"),
            ("ВсС Ρ„Π°ΠΉΠ»Ρ‹", "*.*")
        ]
        file_path = filedialog.askopenfilename(filetypes=image_filetypes)
        if file_path:
            try:
                self.original_image = Image.open(file_path)
                self.display_original_image()  # ΠžΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅ΠΌ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Π½Π° холстС
                self.convert_button.config(state="normal")
            except Exception as e:
                print(f"Ошибка ΠΏΡ€ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ Ρ„Π°ΠΉΠ»Π°: {e}")

ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ изобраТСния Π² ASCII-Π°Ρ€Ρ‚

ΠŸΡ€ΠΎΡ†Π΅ΡΡ создания ASCII-вСрсии исходного изобраТСния состоит ΠΈΠ· Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… этапов:

  • ΠŸΡ€ΠΎΠΏΠΎΡ€Ρ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ΅ ΡƒΠΌΠ΅Π½ΡŒΡˆΠ΅Π½ΠΈΠ΅ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠΈ. Π˜Π·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Π΅Ρ‚ΡΡ Π΄ΠΎ ΠΆΠ΅Π»Π°Π΅ΠΌΠΎΠ³ΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° resize_img. ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅: ASCII-вСрсия получаСтся слСгка вытянутой ΠΏΠΎ Π²Π΅Ρ€Ρ‚ΠΈΠΊΠ°Π»ΠΈ. ΠŸΡ€ΠΎΠΏΠΎΡ€Ρ†ΠΈΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΠ² высоту, Π½ΠΎ ΠΌΠ΅Π»ΠΊΠΈΠ΅ Π΄Π΅Ρ‚Π°Π»ΠΈ ΠΏΡ€ΠΈ этом Ρ‚Π΅Ρ€ΡΡŽΡ‚ΡΡ.
    def resize_img(self, image, new_width=100):
        # ВычисляСм высоту ΠΈ ΡˆΠΈΡ€ΠΈΠ½Ρƒ ΡƒΠΌΠ΅Π½ΡŒΡˆΠ΅Π½Π½ΠΎΠ³ΠΎ изобраТСния, сохраняя ΡΠΎΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΠ΅ сторон
        width, height = image.size
        ratio = height / width 
        new_height = int(new_width * ratio)
        resized_img = image.resize((new_width, new_height))
        return resized_img
  • ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ исходного изобраТСния Π² ΠΎΡ‚Ρ‚Π΅Π½ΠΊΠΈ сСрого. Π­Ρ‚ΠΎ дСлаСтся для упрощСния процСсса ΠΊΠΎΠ½Π²Π΅Ρ€Ρ‚Π°Ρ†ΠΈΠΈ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΎΡ‚Ρ‚Π΅Π½ΠΊΠΈ сСрого ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ Π±ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΡ‡Π½ΠΎ ΠΎΡ†Π΅Π½ΠΈΡ‚ΡŒ ΡΡ€ΠΊΠΎΡΡ‚ΡŒ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ пиксСля. ΠœΠ΅Ρ‚ΠΎΠ΄ pixel_to_grayscale ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Π² качСствС Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ convert("L") ΠΈΠ· Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Pillow для прСобразования изобраТСния Π² ΠΎΡ‚Ρ‚Π΅Π½ΠΊΠΈ сСрого.
    def pixel_to_grayscale(self, image):
        # ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ изобраТСния Π² ΠΎΡ‚Ρ‚Π΅Π½ΠΊΠΈ сСрого
        grayscale_img = image.convert("L")
        return grayscale_img
  • БопоставлСниС ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ пиксСля с ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌ ASCII-символом. ΠœΠ΅Ρ‚ΠΎΠ΄ pixel_to_ascii ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Π² ΠΎΡ‚Ρ‚Π΅Π½ΠΊΠ°Ρ… сСрого ΠΈ ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅Ρ‚ Π΄Π°Π½Π½Ρ‹Π΅ ΠΎ пиксСлях с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° getdata(). Π—Π°Ρ‚Π΅ΠΌ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ пиксСля вычисляСтся индСкс Π² спискС ASCII_CHAR, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ зависит ΠΎΡ‚ Π΅Π³ΠΎ яркости. Π­Ρ‚ΠΎΡ‚ список содСрТит символы, ΠΎΡ‚Ρ€Π°ΠΆΠ°ΡŽΡ‰ΠΈΠ΅ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ ΡƒΡ€ΠΎΠ²Π½ΠΈ яркости, начиная ΠΎΡ‚ самых Ρ‚Π΅ΠΌΠ½Ρ‹Ρ… (@) Π΄ΠΎ самых свСтлых (.) Для вычислСния индСкса ΡΡ€ΠΊΠΎΡΡ‚ΡŒ пиксСля дСлится Π½Π° 25 (ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π² спискС ASCII_CHAR 25 символов, ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… прСдставляСт ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΉ Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½ яркости), ΠΈ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ округляСтся Π²Π½ΠΈΠ· Π΄ΠΎ блиТайшСго Ρ†Π΅Π»ΠΎΠ³ΠΎ числа. Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ получаСтся строка, состоящая ΠΈΠ· ASCII-символов, ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‰ΠΈΡ… исходноС ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅.
    def pixel_to_ascii(self, image):
        # ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈe пиксСлСй изобраТСния Π² ASCII символы
        pixels = image.getdata()
        characters = "".join(ASCII_CHAR[pixel // 25] for pixel in pixels)
        return characters
  • ΠšΠΎΠ½Π²Π΅Ρ€Ρ‚Π°Ρ†ΠΈΡ изобраТСния Π² ASCII-Π°Ρ€Ρ‚. ΠœΠ΅Ρ‚ΠΎΠ΄ convert_to_ascii ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ‚ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠ΅ Ρ‚Ρ€ΠΈ шага – sΠ½Π°Ρ‡Π°Π»Π° ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Π΅Ρ‚ΡΡ Π΄ΠΎ ΠΆΠ΅Π»Π°Π΅ΠΌΠΎΠ³ΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€Π°, Π·Π°Ρ‚Π΅ΠΌ прСобразуСтся Π² ΠΎΡ‚Ρ‚Π΅Π½ΠΊΠΈ сСрого ΠΈ, Π½Π°ΠΊΠΎΠ½Π΅Ρ†, ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ пиксСль прСобразуСтся Π² ASCII-символ. ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½Π½Π°Ρ строка ASCII-символов форматируСтся Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ символ соотвСтствовал ΠΎΠ΄Π½ΠΎΠΌΡƒ пиксСлю исходного изобраТСния, ΠΈ разбиваСтся Π½Π° строки с Π·Π°Π΄Π°Π½Π½ΠΎΠΉ ΡˆΠΈΡ€ΠΈΠ½ΠΎΠΉ.
    def convert_to_ascii(self, image, new_width=100):
        grayscale_image = self.pixel_to_grayscale(self.resize_img(image))
        new_image_data = self.pixel_to_ascii(grayscale_image)
        pixel_nb = len(new_image_data)
        ascii_img = "\n".join(new_image_data[i : i + new_width] for i in range(0, pixel_nb, new_width))
        return ascii_img

Код Π³ΠΎΡ‚ΠΎΠ²ΠΎΠ³ΠΎ прилоТСния ΠΌΠΎΠΆΠ½ΠΎ Π²Π·ΡΡ‚ΡŒ Π² Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ ascii_art.

🐍 Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° питониста
Π‘ΠΎΠ»ΡŒΡˆΠ΅ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹Ρ… ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΎΠ² Π²Ρ‹ Π½Π°ΠΉΠ΄Π΅Ρ‚Π΅ Π½Π° нашСм Ρ‚Π΅Π»Π΅Π³Ρ€Π°ΠΌ-ΠΊΠ°Π½Π°Π»Π΅ Β«Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° питониста»
πŸπŸŽ“ Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Python для собСса
ΠŸΠΎΠ΄Ρ‚ΡΠ½ΡƒΡ‚ΡŒ свои знания ΠΏΠΎ Python Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π½Π° нашСм Ρ‚Π΅Π»Π΅Π³Ρ€Π°ΠΌ-ΠΊΠ°Π½Π°Π»Π΅ Β«Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Python для собСса»
🐍🧩 Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Π·Π°Π΄Π°Ρ‡ ΠΏΠΎ Python
Π˜Π½Ρ‚Π΅Ρ€Π΅ΡΠ½Ρ‹Π΅ Π·Π°Π΄Π°Ρ‡ΠΈ ΠΏΠΎ Python для ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡ‚ΠΈ Π½Π° нашСм Ρ‚Π΅Π»Π΅Π³Ρ€Π°ΠΌ-ΠΊΠ°Π½Π°Π»Π΅ Β«Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Π·Π°Π΄Π°Ρ‡ ΠΏΠΎ PythonΒ»

Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

НСсмотря Π½Π° ΠΏΠΎΡ‚Ρ€ΡΡΠ°ΡŽΡ‰ΠΈΠ΅ возмоТности соврСмСнной ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π½ΠΎΠΉ Π³Ρ€Π°Ρ„ΠΈΠΊΠΈ, ASCII-Π°Ρ€Ρ‚ остаСтся популярным – благодаря своСй ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½ΠΎΠΉ эстСтикС, Π½ΠΎΡΡ‚Π°Π»ΡŒΠ³ΠΈΡ‡Π΅ΡΠΊΠΎΠΌΡƒ ΠΎΡ‡Π°Ρ€ΠΎΠ²Π°Π½ΠΈΡŽ ΠΈ ΠΎΠ±ΡˆΠΈΡ€Π½Ρ‹ΠΌ возмоТностям для творчСства. Π‘ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½Π½ΠΎΠ³ΠΎ Π½Π°Π±ΠΎΡ€Π° тСкстовых символов ASCII-Ρ…ΡƒΠ΄ΠΎΠΆΠ½ΠΈΠΊΠΈ ΡΠΎΠ·Π΄Π°ΡŽΡ‚ ΡƒΠ΄ΠΈΠ²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Π²ΠΈΠ·ΡƒΠ°Π»ΡŒΠ½Ρ‹Π΅ ΠΎΠ±Ρ€Π°Π·Ρ‹, дСмонстрируя своС мастСрство ΠΈ ΡƒΠΌΠ΅Π½ΠΈΠ΅ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π² Ρ€Π°ΠΌΠΊΠ°Ρ… ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½Π½ΠΎΠΉ Β«ΠΏΠ°Π»ΠΈΡ‚Ρ€Ρ‹Β».

НовыС ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρ‹ ΠΏΠΎΡΠ²Π»ΡΡŽΡ‚ΡΡ рСгулярно, ΠΎΠ΄ΠΈΠ½ ΠΈΠ· послСдних интСрСсных ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠ² – ASCII-ΠΊΠΈΠ½ΠΎΡ‚Π΅Π°Ρ‚Ρ€, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ тСкстовыС вСрсии Π½ΠΎΠ²ΠΈΠ½ΠΎΠΊ ΠΊΠΈΠ½ΠΎΠΏΡ€ΠΎΠΊΠ°Ρ‚Π°. Π’ ΠΎΠ±Ρ‰Π΅ΠΌ, нСсмотря Π½Π° свой ΠΏΠΎΡ‡Ρ‚Π΅Π½Π½Ρ‹ΠΉ возраст, ASCII-Π°Ρ€Ρ‚ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Π΅Ρ‚ ΠΆΠΈΡ‚ΡŒ, вдохновляя творчСских людСй Π½Π° Π½ΠΎΠ²Ρ‹Π΅ экспСримСнты, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠ΅ ΠΈΠΌ Π²ΠΎΠΏΠ»ΠΎΡ‚ΠΈΡ‚ΡŒ свои ΠΈΠ΄Π΅ΠΈ Π² самой минималистичной, Π½ΠΎ вмСстС с Ρ‚Π΅ΠΌ элСгантной ΠΈ Π²Ρ‹Ρ€Π°Π·ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ Ρ„ΠΎΡ€ΠΌΠ΅ тСкстового искусства.

***

Π₯ΠΎΡ‡Π΅ΡˆΡŒ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ ΠΊΡ€ΡƒΡ‚Ρ‹Π΅ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρ‹, ΠΊΠ°ΠΊ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ ASCII-Π³Ρ€Π°Ρ„ΠΈΠΊΠΈ? ΠšΡƒΡ€Ρ Β«ΠžΡΠ½ΠΎΠ²Ρ‹ программирования Π½Π° PythonΒ» ΠΎΡ‚ Proglib Academy ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ‚ Ρ‚Π΅Π±Π΅ Π½Π°Ρ‡Π°Ρ‚ΡŒ:

  • Освоишь Π±Π°Π·Ρƒ Python
  • ΠΠ°ΡƒΡ‡ΠΈΡˆΡŒΡΡ Ρ‚Π΅ΡΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠ΄
  • Боздашь Π±ΠΎΡ‚Π° для Π’Π΅Π»Π΅Π³Ρ€Π°ΠΌ, ΠΊΠ°Π»ΡŒΠΊΡƒΠ»ΡΡ‚ΠΎΡ€ для ΠΈΠΏΠΎΡ‚Π΅ΠΊΠΈ, Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ бСзопасных ΠΏΠ°Ρ€ΠΎΠ»Π΅ΠΉ

Π›Π£Π§Π¨Π˜Π• БВАВЬИ ПО Π’Π•ΠœΠ•

Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° программиста
16 ноября 2019

DeepFake-Ρ‚ΡƒΡ‚ΠΎΡ€ΠΈΠ°Π»: создаСм собствСнный Π΄ΠΈΠΏΡ„Π΅ΠΉΠΊ Π² DeepFaceLab

РассказываСм ΠΎ Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ DeepFake ΠΈ шаг Π·Π° шагом учимся Π΄Π΅Π»Π°Ρ‚ΡŒ Π΄ΠΈΠΏΡ„Π΅ΠΉΠΊΠΈ Π² ...
admin
11 дСкабря 2018

ООП Π½Π° Python: ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΠΈ, ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΡ‹ ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π° Python допускаСт Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ»ΠΎΠ³ΠΈΠΈ, Π½ΠΎ Π² Π΅Π³ΠΎ основС...
admin
13 фСвраля 2017

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π° Python: ΠΎΡ‚ Π½ΠΎΠ²ΠΈΡ‡ΠΊΠ° Π΄ΠΎ профСссионала

Пошаговая инструкция для всСх, ΠΊΡ‚ΠΎ Ρ…ΠΎΡ‡Π΅Ρ‚ ΠΈΠ·ΡƒΡ‡ΠΈΡ‚ΡŒΒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π° Python...