6
\$\begingroup\$

I've made some CAPTCHA reader and maker in Python using Tkinter. Do you know if it's possible to keep image and output files in "memory" not writing them on disc? Because right now everything is 'stiffly' made. And what would you do differently?

gui.py

import tkinter as tk
from PIL import Image, ImageTk
import captcha_maker as captcha
import captcha_reader as cap

class MainApplication(tk.Frame):
    """Main window"""
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        self.create_widgets()

    def create_widgets(self):
        """Creating widgets"""
        self.input_label = tk.Label(self, text="Text: ")

        self.input_text = tk.Entry(self)

        self.input_button = tk.Button(self, text="Generate captcha", 
                                        command=self.make_captcha)
        self.img = ImageTk.PhotoImage(Image.open('bin/blank'))
        self.image_label = tk.Label(self, image= self.img)
        self.image_label.image = self.img

        self.strings = tk.StringVar()
        self.read_button = tk.Button(self, text="Read captcha", 
                                        command=self.read_captcha)
        self.output_text = tk.Label(self, textvariable=self.strings)

        self.input_label.grid(row=0, column=0)
        self.input_text.grid(row=0, column=1)
        self.input_button.grid(row=1, column=0)
        self.image_label.grid(row=1, column=1)
        self.read_button.grid(row=2, column=0)
        self.output_text.grid(row=2, column=1)


    def make_captcha(self):
        captcha.make(self.input_text.get())
        self.img2 = ImageTk.PhotoImage(Image.open('bin/result'))
        self.image_label.configure(image=self.img2)
        self.image_label.image = self.img

    def read_captcha(self):
        cap.read()
        with open('bin/output.txt', 'r') as f:
            read_data = f.read().rstrip()
        self.strings.set(read_data)    

if __name__ == "__main__":
    root = tk.Tk()
    MainApplication(root).grid()
    root.mainloop()

captcha_maker.py

from PIL import Image, ImageDraw, ImageFont, ImageTk
import io

def make(text):
    """Making simple and regular captcha"""
    im = Image.new("RGB", (len(text) * 13 , 27), "white")
    im.save('bin/blank', "png")
    base = Image.open('bin/blank').convert('RGBA')
    txt = Image.new('RGBA', base.size, (255,255,255,0))
    fnt = ImageFont.truetype('bin/Ubuntu-B.ttf', 24)
    d = ImageDraw.Draw(txt)
    d.text((0,0), text, font=fnt, fill=(0,0,0,255))
    out = Image.alpha_composite(base, txt)
    out.save("bin/result", "png")

if __name__ == ("__main__"):
    make("one")

captcha_reader.py

import subprocess
def read():
    """Just calling tesseract command from python"""
    subprocess.call(["tesseract", "bin/result", "bin/output"])

if __name__ == "__main__":
    read()
\$\endgroup\$
2
\$\begingroup\$

You can combine these 3 tricks to resolve your problem:

  1. Create your images as string buffers using StringIO. In Python 2 you can import it by: import StringIO; while in Python 3 you can import it by running: import io then use io.StringIO.

  2. Read your images from a string: im = Image.open(io.StringIO.StringIO(buffer))

  3. You can share the images you are interested in across your three modules by making them global variables (How do I share global variables across modules?).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.