# -*- coding: utf-8 -*- # png_b64_conv.py # ========================== # * Version : 0.2 # * Last update : 2019-07-20 # import base64 from argparse import ArgumentParser from datetime import datetime as DateTime from tkinter import StringVar from tkinter import IntVar from tkinter import PhotoImage 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 SAVE_ICON_DATA = \ "iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAAL" \ "EwEAmpwYAAAAQElEQVQ4y2P8////fwYqAhZ8krNmzcIqnpaWhlMPEwOVweA3kBFb" \ "pDAyMhKlGVt8jsAwHDVw1MBRA8kusSmpFQBjIBEgUkrXNAAAAABJRU5ErkJggg==" COPY_ICON_DATA = \ "iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAAL" \ "EwEAmpwYAAAAf0lEQVQ4y81UQQ7AIAgTw1v1TfJZdlqyEBDYyLYetUDRAjAzt0Kg" \ "dQEA20BLB2YTSZ5M3DXyWstNaHF6KwZmFXh4T+GJOWfqczBS1bPq1RkYbYWI1PMx" \ "Rq5lK/D2G+4UakX+o9AqUK4Q5PrSlkPENqYPZXB0+3w3elmV+HTsJA4EdzNqkjxb" \ "vgAAAABJRU5ErkJggg==" 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") def make_img_element(self): buff = "\"{:s}\"\n" buff += fmt.format(IMG_ALT_TEXT, self.image_width, self.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.encoded buff += "\");\n}\n" return buff def save_as_img(self, fname): with open(fname, "w") as writer: writer.write("\n" "\n") writer.write(self.make_img_element()) writer.write("\n") def save_as_css(self, fname): with open(fname, "w") as writer: writer.write("\n" "\n" "\n" "\n" "\n" "\n" "\n") 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.file_open) 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_icon = PhotoImage(data=SAVE_ICON_DATA) self.save_button = ttk.Button(frame3, text="Save to file", command=self.file_save_as, image=self.save_icon, compound=LEFT, width=16) self.save_button.state(["disabled"]) self.save_button.pack(side=LEFT, expand=1, fill=X, padx=(0, 6)) self.copy_icon = PhotoImage(data=COPY_ICON_DATA) self.copy_button = ttk.Button(frame3, text="Copy to clipboard", command=self.copy, image=self.copy_icon, compound=LEFT, 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, width=32, 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 file_open(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 file_save_as(self): ftypes = [("HTML Files", ".html")] fname = filedialog.asksaveasfilename(filetypes=ftypes) if fname: self.save_button.state(["disabled"]) type_ = self.type_var.get() if type_ == IMG: self.converter.save_as_img(fname) self.result_var.set("Saved to " + fname) elif type_ == CSS: self.converter.save_as_css(fname) 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.converter.make_img_element()) self.result_var.set("Copy the IMG element to clipboard") elif type_ == CSS: self.clipboard_clear() self.clipboard_append(self.converter.make_css_list_rule_set()) self.result_var.set("Copy the CSS list rule-set to clipboard") def _main(): parser = ArgumentParser() parser.add_argument("-v", "--version", action="version", version="%(prog)s 0.2") group = parser.add_mutually_exclusive_group() group.add_argument("-i", "--img", help="convert to base64 and save as img element") group.add_argument("-c", "--css", help="convert to base64 and save as css rule-set") args = parser.parse_args() if args.img: conv = PNGToBase64Converter() conv.load(args.img) fname = "base64_img_" fname += DateTime.now().strftime("%M%S") fname += ".html" conv.save_as_img(fname) print("Saved to", fname) elif args.css: conv = PNGToBase64Converter() conv.load(args.css) fname = "base64_css_" fname += DateTime.now().strftime("%M%S") fname += ".html" conv.save_as_css(fname) print("Saved to", fname) else: root = Tk() root.title(TITLE) root.minsize(160, 160) frame = MainFrame(root) frame.mainloop() if __name__ == "__main__": _main()