init
This commit is contained in:
7
image_generator/README
Normal file
7
image_generator/README
Normal file
@@ -0,0 +1,7 @@
|
||||
CorelImg
|
||||
Bilder einbetten
|
||||
Text nicht als Kurve
|
||||
Objektmanager Sigmazeichen entfernen sonst export nicht möglich kein UTF-8
|
||||
|
||||
Install GTK-3 Runtime from here:
|
||||
https://github.com/tschoonj/GTK-for-Windows-Runtime-Environment-Installer/releases
|
||||
98
image_generator/SvgCreatorModel.py
Normal file
98
image_generator/SvgCreatorModel.py
Normal file
@@ -0,0 +1,98 @@
|
||||
from modules.svgcreator import SvgCreator
|
||||
import pandas as pd
|
||||
|
||||
class SvgCreatorModel:
|
||||
arr_errors = []
|
||||
def __init__(self, svg_path, excel_path, output_path):
|
||||
self.svg_path = svg_path
|
||||
self.excel_path = excel_path
|
||||
self.output_path = output_path
|
||||
|
||||
|
||||
def extract_excel(self):
|
||||
df = pd.read_excel(self.excel_path)
|
||||
# Iterate over rows and columns to print each cell
|
||||
for index, row in df.iterrows():
|
||||
svg = row["motiv"]
|
||||
tx1 = row["tx1"]
|
||||
num = str(row["num"]).split('.')[0]
|
||||
tx2 = row["tx2"]
|
||||
tx3 = row["tx3"]
|
||||
tx4 = row["tx4"]
|
||||
|
||||
# Check for NaN values and replace them with None
|
||||
svg = svg if pd.notna(row["motiv"]) else None
|
||||
tx1 = tx1 if pd.notna(row["tx1"]) else None
|
||||
num = num if pd.notna(row["num"]) else None
|
||||
tx2 = tx2 if pd.notna(row["tx2"]) else None
|
||||
tx3 = tx3 if pd.notna(row["tx3"]) else None
|
||||
tx4 = tx4 if pd.notna(row["tx4"]) else None
|
||||
|
||||
if(svg == None):
|
||||
continue
|
||||
self.create_svg(svg, tx1, tx2, tx3, tx4, num)
|
||||
|
||||
self.write_error_excel()
|
||||
self.arr_errors = []
|
||||
|
||||
|
||||
def write_error_excel(self):
|
||||
df = pd.DataFrame(self.arr_errors)
|
||||
df.to_excel(self.output_path+"/errors.xlsx")
|
||||
|
||||
|
||||
def create_svg(self, svg, tx1, tx2, tx3, tx4, num):
|
||||
obj = SvgCreator(self.svg_path+"/"+svg+".svg")
|
||||
if obj.svg_path == 0:
|
||||
print("Pfad existiert nicht")
|
||||
print(self.svg_path+"/"+svg+".svg")
|
||||
tuple_error = [svg, "Pfad existiert nicht"]
|
||||
self.arr_errors.append(tuple_error)
|
||||
|
||||
|
||||
allow_exp = True
|
||||
try:
|
||||
if not None == tx1:
|
||||
tx1 = tx1.split("(")[0]
|
||||
if tx1[-1] == " ":
|
||||
tx1 = tx1[:-1]
|
||||
|
||||
obj.update_text("tx1", tx1)
|
||||
if not None == tx2:
|
||||
tx2 = tx2.split("(")[0]
|
||||
if tx2[-1] == " ":
|
||||
tx2 = tx2[:-1]
|
||||
|
||||
obj.update_text("tx2", tx2)
|
||||
if not None == tx3:
|
||||
tx3 = tx3.split("(")[0]
|
||||
if tx3[-1] == " ":
|
||||
tx3 = tx3[:-1]
|
||||
|
||||
obj.update_text("tx3", tx3)
|
||||
if not None == tx4:
|
||||
tx4 = tx4.split("(")[0]
|
||||
if tx4[-1] == " ":
|
||||
tx4 = tx4[:-1]
|
||||
|
||||
obj.update_text("tx4", tx4)
|
||||
if not None == num:
|
||||
num = num.split("(")[0]
|
||||
if num[-1] == " ":
|
||||
num = num[:-1]
|
||||
|
||||
obj.update_text("num", num)
|
||||
except Exception as e:
|
||||
tuple_error = [svg, e]
|
||||
self.arr_errors.append(tuple_error)
|
||||
allow_exp = False
|
||||
|
||||
if allow_exp:
|
||||
try:
|
||||
obj.export_svg(self.output_path+"/", svg+" "+tx1, 300)
|
||||
except Exception as e:
|
||||
tuple_error = [svg, "Export fehlgeschlagen"]
|
||||
self.arr_errors.append(tuple_error)
|
||||
allow_exp = False
|
||||
|
||||
|
||||
13
image_generator/SvgExportController.py
Normal file
13
image_generator/SvgExportController.py
Normal file
@@ -0,0 +1,13 @@
|
||||
import gui
|
||||
|
||||
class SvgExportController:
|
||||
|
||||
def __init__(self):
|
||||
self.gui = gui.App()
|
||||
self.gui.mainloop()
|
||||
|
||||
|
||||
|
||||
|
||||
if "__main__" == __name__:
|
||||
SvgExportController()
|
||||
74
image_generator/gui.py
Normal file
74
image_generator/gui.py
Normal file
@@ -0,0 +1,74 @@
|
||||
import customtkinter
|
||||
import tkinter as tk
|
||||
from tkinter import filedialog
|
||||
import SvgCreatorModel
|
||||
|
||||
class App(customtkinter.CTk):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
self.title("Exporter")
|
||||
self.geometry("377x170")
|
||||
customtkinter.set_default_color_theme("dark-blue")
|
||||
|
||||
self.entry_svg_folder = customtkinter.CTkEntry(self, width=350, placeholder_text="SVG-Ordner Pfad")
|
||||
self.entry_svg_folder.grid(row=0, column=0, pady=10)
|
||||
self.button_svg_folder = customtkinter.CTkButton(self, text="...", command=self.button_find_svg, width=10)
|
||||
self.button_svg_folder.grid(row=0, column=1)
|
||||
|
||||
self.entry_excel_file = customtkinter.CTkEntry(self, width=350, placeholder_text="EXCEL-Datei Pfad")
|
||||
self.entry_excel_file.grid(row=1, column=0)
|
||||
self.button_excel_file = customtkinter.CTkButton(self, text="...", width=10, command=self.button_find_excel)
|
||||
self.button_excel_file.grid(row=1, column=1)
|
||||
|
||||
self.entry_output = customtkinter.CTkEntry(self, width=350, placeholder_text="OUTPUT-Ordner Pfad")
|
||||
self.entry_output.grid(row=2, column=0)
|
||||
self.button_output = customtkinter.CTkButton(self, text="...", width=10, command=self.button_find_output)
|
||||
self.button_output.grid(row=2, column=1, pady=10)
|
||||
|
||||
self.button_run = customtkinter.CTkButton(self, text="start", width=100, state="disabled", command=self.run)
|
||||
self.button_run.grid(row=3, column=0)
|
||||
|
||||
def button_find_svg(self):
|
||||
file_path = filedialog.askdirectory(title="Select a folder")
|
||||
if file_path:
|
||||
self.entry_svg_folder.delete(0, tk.END)
|
||||
self.entry_svg_folder.insert(0, file_path)
|
||||
self.check_inputs()
|
||||
|
||||
def button_find_output(self):
|
||||
file_path = filedialog.askdirectory(title="Select a folder")
|
||||
if file_path:
|
||||
self.entry_output.delete(0, tk.END)
|
||||
self.entry_output.insert(0, file_path)
|
||||
self.check_inputs()
|
||||
|
||||
def button_find_excel(self):
|
||||
file_path = filedialog.askopenfilename(title="Select a file", filetypes=[("Excel Files", "*.xlsx *.xls")])
|
||||
if file_path:
|
||||
self.entry_excel_file.delete(0, tk.END)
|
||||
self.entry_excel_file.insert(0, file_path)
|
||||
self.check_inputs()
|
||||
|
||||
def check_inputs(self):
|
||||
if all([
|
||||
self.entry_output.get(),
|
||||
self.entry_excel_file.get(),
|
||||
self.entry_svg_folder.get()
|
||||
]):
|
||||
self.button_run.configure(state="normal")
|
||||
|
||||
def run(self):
|
||||
obj = SvgCreatorModel.SvgCreatorModel(self.entry_svg_folder.get(), self.entry_excel_file.get(), self.entry_output.get())
|
||||
self.withdraw() # Hide the main window
|
||||
try:
|
||||
obj.extract_excel()
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
self.deiconify() # Show the main window
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = App()
|
||||
app.mainloop()
|
||||
23
image_generator/modules/csvwriter.py
Normal file
23
image_generator/modules/csvwriter.py
Normal file
@@ -0,0 +1,23 @@
|
||||
import csv
|
||||
import zipfile
|
||||
import os
|
||||
|
||||
|
||||
def write_csv(arr,folder):
|
||||
with open(folder+'/failed_png.csv', 'w', newline='') as csvfile:
|
||||
# Create a CSV writer object
|
||||
writer = csv.writer(csvfile)
|
||||
|
||||
# Write header row if needed
|
||||
writer.writerow(['Produkt', 'Name', 'Grund'])
|
||||
|
||||
for row in arr:
|
||||
writer.writerow([row[0], row[1], row[2]])
|
||||
|
||||
|
||||
|
||||
def zip_folder(folder_path, zip_path):
|
||||
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zip_file:
|
||||
for root, dirs, files in os.walk(folder_path):
|
||||
for file in files:
|
||||
zip_file.write(os.path.join(root, file))
|
||||
18
image_generator/modules/inktest.py
Normal file
18
image_generator/modules/inktest.py
Normal file
@@ -0,0 +1,18 @@
|
||||
import subprocess
|
||||
|
||||
def convert_svg_to_png(svg_path, png_path, dpi):
|
||||
try:
|
||||
subprocess.run(['C:\\Program Files\\Inkscape\\bin\\inkscape.exe', svg_path, '--export-filename', png_path, f'--export-dpi={dpi}'])
|
||||
print(f"Conversion successful: {svg_path} -> {png_path} at {dpi} DPI")
|
||||
except Exception as e:
|
||||
print(f"Conversion failed: {e}")
|
||||
|
||||
# Specify your SVG and PNG file paths
|
||||
input_svg_path = 'C:\\Users\\olgaw\\Desktop\\Andre\\SVGBilderProgramm\\Test\\SVGEXportTest\\images\\btb184.svg'
|
||||
output_png_path = 'output_file33.png'
|
||||
|
||||
# Set the DPI
|
||||
dpi = 300
|
||||
|
||||
# Call the conversion function
|
||||
convert_svg_to_png(input_svg_path, output_png_path, dpi)
|
||||
144
image_generator/modules/svgcreator.py
Normal file
144
image_generator/modules/svgcreator.py
Normal file
@@ -0,0 +1,144 @@
|
||||
from bs4 import BeautifulSoup
|
||||
import cairo
|
||||
import cairosvg
|
||||
import re
|
||||
import io
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
class SvgCreator:
|
||||
# ERROR CODES:
|
||||
# self.svg_path = 0 : file not found
|
||||
# 2: textId not found -- 3: styles string not found -- 4: string not found
|
||||
|
||||
def __init__(self, svg_path):
|
||||
#for Error-Handling
|
||||
try:
|
||||
with open(svg_path, "r", encoding="utf-8") as file:
|
||||
self.svg_path = file.read()
|
||||
except Exception as e:
|
||||
self.svg_path = 0
|
||||
print(e)
|
||||
|
||||
|
||||
def update_text(self, text_id, new_text):
|
||||
# Parse the SVG content
|
||||
soup = BeautifulSoup(self.svg_path, "lxml-xml")
|
||||
|
||||
# Find the text element and get the content
|
||||
text_element = soup.find("text", {"id": text_id})
|
||||
if text_element == None:
|
||||
raise Exception("Inputfeld "+text_id+" nicht gefunden")
|
||||
class_attr = text_element.get("class")
|
||||
class_list = class_attr.split()
|
||||
text_element_content = text_element.getText()
|
||||
|
||||
# Find the string starting with 'fnt' in text-element
|
||||
fnt_class = next((s for s in class_list if s.startswith('fnt')), None)
|
||||
if(fnt_class == None):
|
||||
raise Exception("SVG-Format Muser falsch")
|
||||
######################################
|
||||
# Find the string starting with '.fnt*' in styles-element
|
||||
input_string = self.svg_path
|
||||
match = re.search(r"\."+ fnt_class+ r"\s*\{[^\}]*\}", input_string)
|
||||
if match == None:
|
||||
raise Exception("SVG-Format Muser falsch")
|
||||
css_fnt_str = match.group()
|
||||
# extract the font-size from string
|
||||
font_size = re.search(r"font-size:(\d+\.?\d*)px;", css_fnt_str)
|
||||
if font_size == None:
|
||||
raise Exception("SVG-Format Muser falsch")
|
||||
font_size_ready = (float)(font_size.group(1))
|
||||
|
||||
#extract the font-type from string
|
||||
font_type = re.search(r"font-family:'(.*?)'", css_fnt_str)
|
||||
if font_type == None:
|
||||
raise Exception("SVG-Format Muser falsch")
|
||||
font_type_ready = font_type.group(1)
|
||||
|
||||
######################################
|
||||
# Creating sandbox area to find out the metrics for manipulation later on
|
||||
|
||||
# Convert SVG to PNG
|
||||
png_data = cairosvg.svg2png(self.svg_path.encode('utf-8'))
|
||||
# Create a Cairo image surface from the PNG data
|
||||
image_surface = cairo.ImageSurface.create_from_png(io.BytesIO(png_data))
|
||||
# Create a Cairo context
|
||||
ctx = cairo.Context(image_surface)
|
||||
# Set the font size and font family
|
||||
# Insert extracted font_size_ready
|
||||
# # Insert extracted font_type_ready
|
||||
# Get the text extents
|
||||
ctx.set_font_size(font_size_ready)
|
||||
|
||||
ctx.select_font_face(font_type_ready, cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
|
||||
extents = ctx.text_extents(text_element_content)
|
||||
|
||||
# Get the text width and height from example string
|
||||
# Cal the dimensions if the new font-size it larger
|
||||
text_width_old = str(extents.width)
|
||||
text_height_old = extents.height
|
||||
dimension = (float)(text_width_old)*font_size_ready
|
||||
|
||||
# set the new text. And check its width
|
||||
extents = ctx.text_extents(new_text)
|
||||
text_width_new = extents.width
|
||||
|
||||
#calculate the font-size for the new name based on its width
|
||||
if text_width_new > (float)(text_width_old):
|
||||
# width is larger so its font-size gets smaller and its y-cor adapts to new size
|
||||
# Same sandBox principle as above
|
||||
new_font_size = dimension/text_width_new
|
||||
pp = cairo.Context(image_surface)
|
||||
pp.set_font_size(new_font_size)
|
||||
pp.select_font_face(font_type_ready, cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
|
||||
extents_pp = pp.text_extents(new_text)
|
||||
|
||||
# Calc new y-cor
|
||||
text_height_new = extents_pp.height
|
||||
height_diff = (text_height_old - text_height_new) /2
|
||||
text_element['y'] = str((float)(text_element['y']) - (height_diff))
|
||||
|
||||
# updating with new y-cor and old font-size
|
||||
new_css_fnt_str = css_fnt_str.replace("font-size:"+ str(font_size_ready)+"px", "font-size:"+ str(new_font_size)+"px")
|
||||
else:
|
||||
# width is smaller so the css style (font-size & and y-cor) stays
|
||||
new_css_fnt_str = css_fnt_str
|
||||
|
||||
# Centering the new text by calc updated x-cor and setting it
|
||||
width_diff = ((float)(text_width_old) - (float)(extents.width))/2
|
||||
text_element['x'] = str((float)(text_element['x']) + (width_diff))
|
||||
|
||||
# Update the text element content
|
||||
text_element.string = new_text
|
||||
# Update the CSS style in the SVG
|
||||
style_tag = soup.find("style")
|
||||
style_tag.string = style_tag.string.replace(css_fnt_str, new_css_fnt_str)
|
||||
# Convert the updated BeautifulSoup object back to a string
|
||||
new_svg = str(soup)
|
||||
new_svg = new_svg.replace(css_fnt_str, new_css_fnt_str)
|
||||
self.svg_path = new_svg
|
||||
return 1
|
||||
|
||||
def export_svg(self, export_path, export_name, dpi_value):
|
||||
# Save the modified SVG
|
||||
with open(export_path+export_name+".svg", "w") as file:
|
||||
file.write(self.svg_path)
|
||||
# Convert the modified SVG to a PNG image with the specified DPI
|
||||
|
||||
cairosvg.svg2png(url=export_path+export_name+".svg",
|
||||
write_to=export_path+export_name+".png",
|
||||
dpi=dpi_value, unsafe=True)
|
||||
|
||||
self.convert_svg_to_png(export_path+export_name+".svg", export_path+export_name+".png", dpi_value)
|
||||
# Remove the Junk-Data
|
||||
os.remove(export_path+export_name+".svg")
|
||||
return 1
|
||||
|
||||
|
||||
def convert_svg_to_png(self, svg_path, png_path, dpi):
|
||||
try:
|
||||
subprocess.run(['C:\\Program Files\\Inkscape\\bin\\inkscape.exe', svg_path, '--export-filename', png_path, f'--export-dpi={dpi}'])
|
||||
print(f"Conversion successful: {svg_path} -> {png_path} at {dpi} DPI")
|
||||
except Exception as e:
|
||||
print(f"Conversion failed: {e}")
|
||||
BIN
image_generator/output/SVGExport.exe
Normal file
BIN
image_generator/output/SVGExport.exe
Normal file
Binary file not shown.
BIN
image_generator/output/SvgExportController.exe
Normal file
BIN
image_generator/output/SvgExportController.exe
Normal file
Binary file not shown.
5
image_generator/requirements.txt
Normal file
5
image_generator/requirements.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
customtkinter
|
||||
beautifulsoup4
|
||||
pycairo
|
||||
cairosvg
|
||||
pandas
|
||||
Reference in New Issue
Block a user