Skip to content

Commit

Permalink
image print
Browse files Browse the repository at this point in the history
  • Loading branch information
Dodoooh committed Dec 15, 2024
1 parent b1ac00b commit 77c59bc
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 72 deletions.
50 changes: 41 additions & 9 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@

app = Flask(__name__)

# Standard-Dateipfad für Settings
# Standard-Dateipfad für Settings und Uploads
SETTINGS_FILE = "settings.json"
UPLOAD_FOLDER = "uploads"
os.makedirs(UPLOAD_FOLDER, exist_ok=True)

FONT_PATH = "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf"

# Standard-Einstellungen
Expand All @@ -21,10 +24,10 @@
"font_size": 50,
"alignment": "left",
"rotate": "0", # Optionen: "0", "90", "180", "270"
"threshold": 70.0, # Schwellenwert für Schwarz-Weiß-Konvertierung
"dither": False, # Dithering verwenden oder nicht
"compress": False, # Kompression verwenden oder nicht
"red": True # Zweifarbiger Druck (Schwarz/Rot) verwenden
"threshold": 70.0,
"dither": False,
"compress": False,
"red": True
}

# Einstellungen laden/speichern
Expand Down Expand Up @@ -107,15 +110,14 @@ def api_text():
return jsonify({"error": "Kein Text angegeben."}), 400

try:
# Label erzeugen und drucken
image_path = create_label_image(text, alignment)
send_to_printer(image_path)
return jsonify({"success": True, "message": "Textdruckauftrag gesendet."})
except Exception as e:
return jsonify({"error": str(e)}), 500

def create_label_image(html_text, alignment="left"):
"""Erstellt ein Labelbild mit dynamischer Höhe und unterstützt Ausrichtung."""
"""Erstellt ein Labelbild mit dynamischer Höhe."""
width = 696
parser = TextParser()
parser.feed(html_text)
Expand Down Expand Up @@ -179,12 +181,42 @@ def create_label_image(html_text, alignment="left"):
x += text_width + 5
y += line_height + line_spacing

image_path = "label.png"
image_path = os.path.join(UPLOAD_FOLDER, "label.png")
image.save(image_path)
return image_path

@app.route("/api/image/", methods=["POST"])
def print_image():
"""Verarbeitet und druckt hochgeladene Bilder."""
if "image" not in request.files:
return jsonify({"error": "Kein Bild hochgeladen."}), 400

image_file = request.files["image"]
if image_file.filename == "":
return jsonify({"error": "Kein Bild ausgewählt."}), 400

try:
image_path = os.path.join(UPLOAD_FOLDER, image_file.filename)
image_file.save(image_path)
resized_image_path = resize_image(image_path)
send_to_printer(resized_image_path)
return jsonify({"success": True, "message": "Bild erfolgreich gedruckt!"})
except Exception as e:
return jsonify({"error": str(e)}), 500

def resize_image(image_path):
"""Passt die Größe des Bildes an die Druckbreite an."""
max_width = 696
with Image.open(image_path) as img:
aspect_ratio = img.height / img.width
new_height = int(max_width * aspect_ratio)
img = img.resize((max_width, new_height), Image.ANTIALIAS)
resized_path = os.path.join(UPLOAD_FOLDER, "resized_" + os.path.basename(image_path))
img.save(resized_path)
return resized_path

def send_to_printer(image_path):
"""Sendet das Label an den Drucker."""
"""Sendet das Bild oder Label an den Drucker."""
qlr = BrotherQLRaster(settings["printer_model"])
qlr.exception_on_warning = True
instructions = convert(
Expand Down
44 changes: 42 additions & 2 deletions static/scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ document.addEventListener("DOMContentLoaded", () => {
const copyToClipboardButton = document.getElementById("copy-to-clipboard");
const resultSection = document.getElementById("result-section");
const resultContainer = document.getElementById("result");
const imageForm = document.getElementById("image-form");
const imageUpload = document.getElementById("image-upload");
const imagePreview = document.getElementById("image-preview");
const previewImg = document.getElementById("preview-img");

// Initial Dark Mode setzen basierend auf Systemeinstellungen oder localStorage
function setInitialMode() {
Expand Down Expand Up @@ -147,6 +151,44 @@ document.addEventListener("DOMContentLoaded", () => {
.catch((error) => alert("Fehler beim Kopieren in die Zwischenablage."));
}

// Bildvorschau
imageUpload.addEventListener("change", () => {
const file = imageUpload.files[0];
if (file) {
const reader = new FileReader();
reader.onload = (e) => {
previewImg.src = e.target.result;
imagePreview.classList.remove("hidden");
};
reader.readAsDataURL(file);
}
});

// Bild drucken
imageForm.addEventListener("submit", async (e) => {
e.preventDefault();
const formData = new FormData();
const file = imageUpload.files[0];
if (!file) {
alert("Bitte wählen Sie ein Bild aus!");
return;
}

formData.append("image", file);

try {
const response = await fetch("/api/image/", {
method: "POST",
body: formData,
});
const result = await response.json();
alert(result.message || "Bild wurde gedruckt!");
} catch (error) {
console.error("Fehler beim Drucken des Bildes:", error);
alert("Fehler beim Drucken.");
}
});

// Einstellungen ein- und ausklappen
settingsToggle.addEventListener("click", () => {
const isHidden = settingsContent.classList.contains("hidden");
Expand All @@ -158,8 +200,6 @@ document.addEventListener("DOMContentLoaded", () => {

// Initial Dark Mode setzen
setInitialMode();

// Dark Mode Toggle
darkModeToggle.addEventListener("click", toggleDarkMode);

// Einstellungen laden
Expand Down
15 changes: 15 additions & 0 deletions static/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -251,4 +251,19 @@ body.dark-mode .secondary-button {

.icon-button:hover {
color: #0056b3;
}

.image-preview {
margin-top: 1rem;
padding: 1rem;
background: #f9f9f9;
border: 1px solid #ccc;
border-radius: 5px;
}

.image-preview img {
max-width: 100%;
height: auto;
border: 1px solid #ccc;
border-radius: 5px;
}
78 changes: 17 additions & 61 deletions templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,77 +47,33 @@ <h2>Text drucken</h2>
</form>
</section>

<!-- Ergebnisbereich -->
<!-- JSON Ergebnis -->
<section class="card hidden" id="result-section">
<div class="result-header">
<h2>JSON Output:</h2>
<h2>Ergebnis</h2>
<button id="copy-to-clipboard" class="icon-button" aria-label="Copy JSON">📋</button>
</div>
<div id="result" class="json-result"></div>
</section>

<!-- Einklappbare Einstellungen -->
<!-- Bild hochladen und drucken -->
<section class="card">
<h2 class="collapsible-header">Einstellungen <span id="settings-toggle"></span></h2>
<div id="settings-content" class="collapsible-content hidden">
<form id="settings-form">
<fieldset>
<legend>Druckerkonfiguration</legend>
<div class="form-group">
<label for="printer_uri">Drucker URI:</label>
<input type="text" id="printer_uri" placeholder="tcp://192.168.1.100">
</div>
<div class="form-group">
<label for="printer_model">Druckermodell:</label>
<input type="text" id="printer_model" placeholder="QL-800">
</div>
<div class="form-group">
<label for="label_size">Label-Größe:</label>
<select id="label_size">
<option value="62">62 mm</option>
<option value="29">29 mm</option>
<option value="12">12 mm</option>
</select>
</div>
</fieldset>

<fieldset>
<legend>Druckeinstellungen</legend>
<div class="form-group">
<label for="rotate">Rotation:</label>
<select id="rotate">
<option value="0"></option>
<option value="90">90°</option>
<option value="180">180°</option>
<option value="270">270°</option>
</select>
</div>
<div class="form-group">
<label for="threshold">Schwellenwert:</label>
<input type="number" id="threshold" min="0" max="100" step="1" value="70">
</div>
<div class="form-group">
<label for="dither">Dithering:</label>
<select id="dither">
<option value="false">Deaktiviert</option>
<option value="true">Aktiviert</option>
</select>
</div>
<div class="form-group">
<label for="red">Zweifarbiger Druck (Schwarz/Rot):</label>
<select id="red">
<option value="true">Aktiviert</option>
<option value="false">Deaktiviert</option>
</select>
</div>
</fieldset>

<div class="form-actions">
<button type="button" class="primary-button" id="save-settings">Speichern</button>
</div>
</form>
<h2>Bild hochladen und drucken</h2>
<form id="image-form" enctype="multipart/form-data">
<div class="form-group">
<label for="image-upload">Bild auswählen:</label>
<input type="file" id="image-upload" accept="image/*">
</div>
<div class="form-actions">
<button type="submit" class="primary-button">Bild drucken</button>
</div>
</form>
<div id="image-preview" class="image-preview hidden">
<h3>Vorschau:</h3>
<img id="preview-img" src="#" alt="Bildvorschau">
</div>
</section>

</main>
</div>

Expand Down

0 comments on commit 77c59bc

Please sign in to comment.