# -*- coding: utf-8 -*- # png_b64_conv.py # ========================== # * Version : 0.1 # * Last update : 2019-07-12 # import base64 from datetime import datetime as DateTime from tkinter import StringVar from tkinter import IntVar from tkinter import Tk from tkinter import filedialog from tkinter import ttk from tkinter import TOP, LEFT, NW, BOTH, X TITLE = "PNG to Base64 converter" STEP1_TEXT = u"1. 画像ファイルを選択してください" STEP2_TEXT = u"2. 変換方法を選択してください" STEP3_TEXT = u"3. 出力方法を選択してください" IMG = 0 CSS = 1 IMG_ALT_TEXT = u"実行結果" class PNGToBase64Converter: def __init__(self): self.clear() def clear(self): self.encoded = None self.encoded_length = 0 self.image_width = 0 self.image_height = 0 def load(self, fname): with open(fname, "rb") as istream: png_data = istream.read() self.encoded = base64.b64encode(png_data).decode() self.encoded_length = len(self.encoded) self.image_width = int.from_bytes(png_data[16:20], "big") self.image_height = int.from_bytes(png_data[20:24], "big") class MainFrame(ttk.Frame): def __init__(self, master): super().__init__(master) self.configure(padding=8) self.pack(expand=1, fill=BOTH, anchor=NW) self.make_style() self.create_widget() self.converter = PNGToBase64Converter() def make_style(self): s = ttk.Style() s.configure("Heading.TLabel", font=("", 10)) s.configure("Result.TLabel", font=("", 10), padding=4, background="#000000", foreground="#ffffff") s.configure("File.TEntry", padding=4) def create_widget(self): # row 1 step1_label = ttk.Label(self, text=STEP1_TEXT, style="Heading.TLabel") step1_label.pack(side=TOP, fill=X, pady=(0, 4)) # row 2 frame1 = ttk.Frame(self) frame1.pack(side=TOP, fill=X, pady=(0, 8)) file_label = ttk.Label(frame1, text="File:") file_label.pack(side=LEFT, padx=(0, 2)) self.file_var = StringVar() file_entry = ttk.Entry(frame1, textvariable=self.file_var, style="File.TEntry", width=32) file_entry.state(["readonly"]) file_entry.pack(side=LEFT, expand=1, fill=X, padx=(0, 4)) open_button = ttk.Button(frame1, text="OPEN", command=self.show_open_dialog) open_button.pack(side=LEFT) # row 3 step2_label = ttk.Label(self, text=STEP2_TEXT, style="Heading.TLabel") step2_label.pack(side=TOP, fill=X, pady=(0, 4)) # row 4 frame2 = ttk.Frame(self) frame2.pack(side=TOP, fill=X, pady=(0, 8)) self.type_var = IntVar() self.type_var.set(IMG) rb1 = ttk.Radiobutton(frame2, text="IMG element", variable=self.type_var, value=IMG, command=self.radio_button_clicked) rb1.pack(side=TOP, fill=X, padx=(20, 0)) rb2 = ttk.Radiobutton(frame2, text="CSS list rule-set", variable=self.type_var, value=CSS, command=self.radio_button_clicked) rb2.pack(side=TOP, fill=X, padx=(20, 0)) # row 5 step3_label = ttk.Label(self, text=STEP3_TEXT, style="Heading.TLabel") step3_label.pack(side=TOP, fill=X, pady=(0, 4)) # row 6 frame3 = ttk.Frame(self) frame3.pack(side=TOP, fill=X, pady=(0, 8)) self.save_button = ttk.Button(frame3, text="Save to file", command=self.save, width=16) self.save_button.state(["disabled"]) self.save_button.pack(side=LEFT, expand=1, fill=X, padx=(0, 6)) self.copy_button = ttk.Button(frame3, text="Copy to clipboard", command=self.copy, width=16) self.copy_button.state(["disabled"]) self.copy_button.pack(side=LEFT, expand=1, fill=X) # row 7 self.result_var = StringVar() self.result_var.set("(result)") result_label = ttk.Label(self, textvariable=self.result_var, style="Result.TLabel") result_label.pack(side=TOP, fill=X) def radio_button_clicked(self): if self.copy_button.instate(["!disabled"]) == True: self.save_button.state(["!disabled"]) self.result_var.set("(result)") def show_open_dialog(self): ftypes = [("PNG Image Files", ".png")] fname = filedialog.askopenfilename(filetypes=ftypes) if fname: self.file_var.set(fname) self.converter.load(fname) self.save_button.state(["!disabled"]) self.copy_button.state(["!disabled"]) self.result_var.set("(result)") def make_img_element(self): buff = "\"{:s}\"\n" buff += fmt.format(IMG_ALT_TEXT, self.converter.image_width, self.converter.image_height) return buff def make_css_list_rule_set(self): buff = "li {\n" buff += "\tlist-style-image: url(\"data:image/png;base64," buff += self.converter.encoded buff += "\");\n}\n" return buff def save(self): self.save_button.state(["disabled"]) type_ = self.type_var.get() if type_ == IMG: fname = "base64_img_" fname += DateTime.now().strftime("%M%S") fname += ".html" with open(fname, "w") as writer: writer.write("\n" "\n") writer.write(self.make_img_element()) writer.write("\n") self.result_var.set("Saved to " + fname) elif type_ == CSS: fname = "base64_css_" fname += DateTime.now().strftime("%M%S") fname += ".html" with open(fname, "w") as writer: writer.write("\n" "\n" "\n" "\n" "\n" "\n" "\n") self.result_var.set("Saved to " + fname) def copy(self): type_ = self.type_var.get() if type_ == IMG: self.clipboard_clear() self.clipboard_append(self.make_img_element()) self.result_var.set("Copy the IMG element to clipboard") elif type_ == CSS: self.clipboard_clear() self.clipboard_append(self.make_css_list_rule_set()) self.result_var.set("Copy the CSS list rule-set to clipboard") def _main(): root = Tk() root.title(TITLE) frame = MainFrame(root) frame.mainloop() if __name__ == "__main__": _main()