Version 0.1
This commit is contained in:
154
src/ink-calc.py
Normal file
154
src/ink-calc.py
Normal file
@@ -0,0 +1,154 @@
|
||||
import numpy as np
|
||||
import os
|
||||
import sys
|
||||
import tkinter as tk
|
||||
import threading
|
||||
import webbrowser
|
||||
from PIL import Image
|
||||
from tkinter import filedialog, ttk
|
||||
|
||||
# Ink Coverage Calculator
|
||||
# Version: 0.1
|
||||
# License: GPL 3.0 or Later
|
||||
# Author: Ze'ev Schurmann
|
||||
# Git Repo: https://git.zaks.web.za/thisiszeev/ink-calc
|
||||
# Dependancies: NumPy, PIL, TKinter
|
||||
# Support my work: $5 buys me a cup of coffee
|
||||
# $10 buys me a nice burger
|
||||
# $20 buys me a bottle of wine
|
||||
# https://paypal.me/thisiszeev
|
||||
|
||||
stop_processing = False
|
||||
|
||||
def rgb_to_cmyk(r, g, b):
|
||||
c = 1 - (r / 255.0)
|
||||
m = 1 - (g / 255.0)
|
||||
y = 1 - (b / 255.0)
|
||||
k = min(c, m, y)
|
||||
if k < 1:
|
||||
c = (c - k) / (1 - k)
|
||||
m = (m - k) / (1 - k)
|
||||
y = (y - k) / (1 - k)
|
||||
else:
|
||||
c = m = y = 0
|
||||
return c * 100, m * 100, y * 100, k * 100
|
||||
|
||||
def calculate_ink_coverage(image_path, progress_var, result_labels, filename_label, root, button):
|
||||
global stop_processing
|
||||
image = Image.open(image_path).convert("RGBA")
|
||||
pixels = np.array(image)
|
||||
|
||||
total_pixels = pixels.shape[0] * pixels.shape[1]
|
||||
processed_pixels = 0
|
||||
|
||||
total_c, total_m, total_y, total_k, total_w = 0, 0, 0, 0, 0
|
||||
|
||||
filename_label.config(text=os.path.basename(image_path))
|
||||
|
||||
for color in ["C", "M", "Y", "K", "W"]:
|
||||
result_labels[color].config(text=f"{color}: 0.00%")
|
||||
|
||||
for i, row in enumerate(pixels):
|
||||
for j, (r, g, b, a) in enumerate(row):
|
||||
if stop_processing:
|
||||
button.config(text="Open PNG File", command=lambda: open_file(progress_var, result_labels, filename_label, root, button))
|
||||
return
|
||||
|
||||
c, m, y, k = rgb_to_cmyk(r, g, b)
|
||||
w = (a / 255.0) * 100
|
||||
|
||||
total_c += (c * a / 255)
|
||||
total_m += (m * a / 255)
|
||||
total_y += (y * a / 255)
|
||||
total_k += (k * a / 255)
|
||||
total_w += w
|
||||
|
||||
processed_pixels += 1
|
||||
progress = (processed_pixels / total_pixels) * 100
|
||||
if processed_pixels % (total_pixels // 1000) == 0:
|
||||
progress_var.set(progress)
|
||||
root.update_idletasks()
|
||||
|
||||
avg_c = total_c / total_pixels
|
||||
avg_m = total_m / total_pixels
|
||||
avg_y = total_y / total_pixels
|
||||
avg_k = total_k / total_pixels
|
||||
avg_w = total_w / total_pixels
|
||||
|
||||
result_labels["C"].config(text=f"C: {avg_c:.2f}%")
|
||||
result_labels["M"].config(text=f"M: {avg_m:.2f}%")
|
||||
result_labels["Y"].config(text=f"Y: {avg_y:.2f}%")
|
||||
result_labels["K"].config(text=f"K: {avg_k:.2f}%")
|
||||
result_labels["W"].config(text=f"W: {avg_w:.2f}%")
|
||||
|
||||
button.config(text="Open PNG File", command=lambda: open_file(progress_var, result_labels, filename_label, root, button))
|
||||
|
||||
def open_file(progress_var, result_labels, filename_label, root, button):
|
||||
global stop_processing
|
||||
file_path = filedialog.askopenfilename(filetypes=[("PNG files", "*.png")])
|
||||
if file_path:
|
||||
stop_processing = False
|
||||
button.config(text="Stop", command=lambda: stop_process(button))
|
||||
threading.Thread(target=calculate_ink_coverage, args=(file_path, progress_var, result_labels, filename_label, root, button), daemon=True).start()
|
||||
|
||||
def stop_process(button):
|
||||
global stop_processing
|
||||
stop_processing = True
|
||||
button.config(text="Open PNG File", command=lambda: open_file(progress_var, result_labels, filename_label, root, button))
|
||||
|
||||
def copy_to_clipboard(root, filename_label, result_labels):
|
||||
clipboard_text = f"{filename_label.cget('text')}\n"
|
||||
clipboard_text += "\n".join([result_labels[color].cget('text') for color in ["C", "M", "Y", "K", "W"]])
|
||||
root.clipboard_clear()
|
||||
root.clipboard_append(clipboard_text)
|
||||
root.update()
|
||||
|
||||
def open_url(url):
|
||||
webbrowser.open(url)
|
||||
|
||||
def main():
|
||||
root = tk.Tk()
|
||||
root.title("Ink Coverage Calculator v0.1")
|
||||
|
||||
frame = tk.Frame(root)
|
||||
frame.pack(padx=10, pady=10)
|
||||
|
||||
filename_label = tk.Label(frame, text="", fg="blue")
|
||||
filename_label.pack()
|
||||
|
||||
progress_var = tk.DoubleVar()
|
||||
progress_bar = ttk.Progressbar(frame, variable=progress_var, maximum=100, length=400)
|
||||
progress_bar.pack(pady=5)
|
||||
|
||||
result_labels = {}
|
||||
for color in ["C", "M", "Y", "K", "W"]:
|
||||
label = tk.Label(frame, text=f"{color}: 0.00%")
|
||||
label.pack()
|
||||
result_labels[color] = label
|
||||
|
||||
button_frame = tk.Frame(frame)
|
||||
button_frame.pack(pady=5)
|
||||
|
||||
open_button = tk.Button(button_frame, text="Open PNG File", command=lambda: open_file(progress_var, result_labels, filename_label, root, open_button))
|
||||
open_button.grid(row=0, column=0, padx=5)
|
||||
|
||||
copy_button = tk.Button(button_frame, text="Copy to Clipboard", command=lambda: copy_to_clipboard(root, filename_label, result_labels))
|
||||
copy_button.grid(row=0, column=1, padx=5)
|
||||
|
||||
links_frame = tk.Frame(frame)
|
||||
links_frame.pack(pady=5)
|
||||
|
||||
buttons = [
|
||||
("License", "https://www.gnu.org/licenses/gpl-3.0.html"),
|
||||
("Git Repo", "https://git.zaks.web.za/thisiszeev/ink-calc"),
|
||||
("Documentation", "https://git.zaks.web.za/thisiszeev/ink-calc/wiki"),
|
||||
("Buy me a Burger", "https://paypal.me/thisiszeev")
|
||||
]
|
||||
|
||||
for i, (label, url) in enumerate(buttons):
|
||||
tk.Button(links_frame, text=label, command=lambda u=url: open_url(u)).grid(row=0, column=i, padx=5)
|
||||
|
||||
root.mainloop()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user