# -*- 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 = "\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"
"- AAA
\n"
"- BBB
\n"
"- CCC
\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()