# -*- 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 = "\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"
"