From 88147231f0279e3cbfd11df1d9735624b308f8e1 Mon Sep 17 00:00:00 2001 From: joel Date: Fri, 10 Apr 2026 11:00:13 +0200 Subject: [PATCH] v1.1 --- README.md | 40 ++++++- deploy.php | 6 - index.php | 327 +++++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 303 insertions(+), 70 deletions(-) delete mode 100644 deploy.php diff --git a/README.md b/README.md index ceed7b6..d01aff0 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,36 @@ -Noch zu machen: -- Max. Anzahl upload von 15 Bildern per upload -- Benutzer darf seine eigenen Bilder "löschen" werden aber nur in einen anderen Ordner verschoben -- Bild Kompression bei der vorschau, um dir ladegeschwindigkeit zu verschnellern und das netzwerk nicht zu überlasten. \ No newline at end of file +# Fotobox Projekt-Updates + +Dieses Dokument beschreibt die vorgenommenen technischen Änderungen an der `index.php`. + +## v1.1 - Fix für gedrehte Bilder (Aktuell) + +### Problembeschreibung +Bilder, die mit dem Smartphone im Hochformat (oder quer) aufgenommen wurden, erschienen in der Galerie-Vorschau (Thumbnails) oft um 90° nach links gedreht. + +### Technische Lösung +Das Problem lag in der Thumbnail-Generierung mittels PHP GD. Smartphones speichern die korrekte Ausrichtung oft nur in den EXIF-Metadaten, die PHP standardmäßig beim Skalieren ignoriert hat. + +* **Änderung**: Die Funktion `createThumbnail()` wurde erweitert. +* Sie nutzt nun `exif_read_data()` (falls auf dem Server verfügbar), um den `Orientation`-Tag aus JPEGs auszulesen. +* Basierend auf diesem Tag wird das Bild mittels `imagerotate()` korrekt gedreht, *bevor* das Thumbnail resampled und gespeichert wird. + +*Hinweis:* Diese Änderung betrifft nur Bilder, die *nach* diesem Update hochgeladen werden. Um alte, falsch gedrehte Thumbnails zu korrigieren, muss der Inhalt des Ordners `/thumbnails/` auf dem Server gelöscht werden, damit sie neu generiert werden. + +--- + +## v1.0 - Basis-Funktionen & Performance + +Initiales Update mit Kernfunktionalitäten. + +### 1. Upload-Limitierung +* Maximal **15 Bilder** pro Upload-Vorgang möglich. +* Validierung erfolgt sowohl im Frontend (JS) als auch Backend (PHP). + +### 2. Bild-Kompression (Thumbnails) +* Automatische Erstellung von optimierten Vorschaubildern im Ordner `/thumbnails/`. +* Galerie lädt Thumbnails für schnellere Ladezeiten; Originale werden im Ordner `/uploads/` gespeichert und erst in der Vollansicht geladen. + +### 3. Benutzerbasierte Löschfunktion +* Über `LocalStorage` merkt sich der Browser, welche Bilder der Nutzer hochgeladen hat. +* Lösch-Button erscheint in der Lightbox nur für eigene Bilder. +* Bilder werden nicht gelöscht, sondern in `/deleted_uploads/` verschoben. \ No newline at end of file diff --git a/deploy.php b/deploy.php deleted file mode 100644 index 3db85fc..0000000 --- a/deploy.php +++ /dev/null @@ -1,6 +0,0 @@ -&1'); -echo $output; -?> \ No newline at end of file diff --git a/index.php b/index.php index ba97d3b..4c90235 100644 --- a/index.php +++ b/index.php @@ -1,6 +1,13 @@ = 1) { + $newWidth = $srcWidth; + $newHeight = $srcHeight; + } else { + $newWidth = (int)($srcWidth * $ratio); + $newHeight = (int)($srcHeight * $ratio); + } + + $destImage = imagecreatetruecolor($newWidth, $newHeight); + + // Transparenz für PNG und WEBP beibehalten + if ($mime == 'image/png' || $mime == 'image/webp') { + imagealphablending($destImage, false); + imagesavealpha($destImage, true); + $transparent = imagecolorallocatealpha($destImage, 255, 255, 255, 127); + imagefilledrectangle($destImage, 0, 0, $newWidth, $newHeight, $transparent); + } + + imagecopyresampled($destImage, $sourceImage, 0, 0, 0, 0, $newWidth, $newHeight, $srcWidth, $srcHeight); + + // Thumbnail speichern + switch ($mime) { + case 'image/jpeg': imagejpeg($destImage, $destPath, 80); break; + case 'image/png': imagepng($destImage, $destPath, 8); break; + case 'image/gif': imagegif($destImage, $destPath); break; + case 'image/webp': imagewebp($destImage, $destPath, 80); break; + } + + imagedestroy($sourceImage); + imagedestroy($destImage); + return true; +} + +// -- LÖSCHEN LOGIK -- +if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'delete') { + $fileToDelete = basename($_POST['filename']); + + if (is_file($upload_verzeichnis . $fileToDelete)) { + // Verschiebe Originalbild + rename($upload_verzeichnis . $fileToDelete, $deleted_verzeichnis . $fileToDelete); + + // Verschiebe Thumbnail, falls vorhanden + if (is_file($thumbnail_verzeichnis . $fileToDelete)) { + rename($thumbnail_verzeichnis . $fileToDelete, $deleted_verzeichnis . 'thumb_' . $fileToDelete); + } + + echo json_encode(['success' => true]); + } else { + echo json_encode(['success' => false, 'error' => 'Datei nicht gefunden.']); + } + exit; +} + +// -- UPLOAD LOGIK -- +if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['photos'])) { + // Limit auf 15 Bilder pro Upload serverseitig prüfen + if (count($_FILES['photos']['tmp_name']) > 15) { + echo json_encode(['success' => false, 'error' => 'Maximal 15 Bilder auf einmal erlaubt.']); + exit; + } + + $cleanName = 'Foto'; + $uploadedCount = 0; + $uploadedFiles = []; // Speichert die Namen für das LocalStorage des Nutzers + + foreach ($_FILES['photos']['tmp_name'] as $key => $tmpName) { + if ($tmpName != "") { + $extension = strtolower(pathinfo($_FILES['photos']['name'][$key], PATHINFO_EXTENSION)); + $newName = $cleanName . '_' . time() . '_' . substr(md5(uniqid()), 0, 6) . '.' . $extension; + $destination = $upload_verzeichnis . $newName; + $thumbDestination = $thumbnail_verzeichnis . $newName; + + if (move_uploaded_file($tmpName, $destination)) { + $uploadedCount++; + $uploadedFiles[] = $newName; + + // Erstelle Thumbnail (jetzt mit Rotationskorrektur) + createThumbnail($destination, $thumbDestination); + } + } + } + + echo json_encode([ + 'success' => true, + 'count' => $uploadedCount, + 'newTotal' => get_image_count($upload_verzeichnis), + 'uploadedFiles' => $uploadedFiles + ]); + exit; +} + $current_count = get_image_count($upload_verzeichnis); -// Bilder für die Galerie laden (nur die neuesten 30, um Abstürze am Handy zu vermeiden) +// Bilder für die Galerie laden (nur die neuesten 30) $gallery_images = []; if (is_dir($upload_verzeichnis)) { $files = scandir($upload_verzeichnis); @@ -25,35 +169,8 @@ if (is_dir($upload_verzeichnis)) { // ZUVERLÄSSIGE SORTIERUNG: Alphabetisch absteigend, da Dateiname = Zeitstempel rsort($valid_files); - $gallery_images = array_slice($valid_files, 0, 30); } - -if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_FILES['photos'])) { - $cleanName = 'Foto'; - - if (!is_dir($upload_verzeichnis)) { - mkdir($upload_verzeichnis, 0777, true); - } - - $uploadedCount = 0; - foreach ($_FILES['photos']['tmp_name'] as $key => $tmpName) { - if ($tmpName != "") { - $extension = strtolower(pathinfo($_FILES['photos']['name'][$key], PATHINFO_EXTENSION)); - $newName = $cleanName . '_' . time() . '_' . substr(md5(uniqid()), 0, 6) . '.' . $extension; - if (move_uploaded_file($tmpName, $upload_verzeichnis . $newName)) { - $uploadedCount++; - } - } - } - - echo json_encode([ - 'success' => true, - 'count' => $uploadedCount, - 'newTotal' => get_image_count($upload_verzeichnis) - ]); - exit; -} ?> @@ -65,7 +182,6 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_FILES['photos'])) {