{"id":244,"date":"2026-03-21T15:33:16","date_gmt":"2026-03-21T14:33:16","guid":{"rendered":"https:\/\/nolympiakoeln.de\/?page_id=244"},"modified":"2026-03-21T15:52:57","modified_gmt":"2026-03-21T14:52:57","slug":"profilbild-generator","status":"publish","type":"page","link":"https:\/\/nolympiakoeln.de\/index.php\/profilbild-generator\/","title":{"rendered":"Profilbild-Generator"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Zeig dein Nein:<\/p>\n\n\n\n<!DOCTYPE html>\n<html lang=\"de\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Dein Nolympia Profilbild!<\/title>\n    <style>\n        * {\n            margin: 0;\n            padding: 0;\n            box-sizing: border-box;\n        }\n        \n        body {\n            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n            background: #f5f5f5;\n            min-height: 100vh;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            padding: 16px;\n        }\n        \n        .container {\n            background: white;\n            border-radius: 12px;\n            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n            max-width: 380px;\n            width: 100%;\n            padding: 24px;\n            border: 1px solid #e0e0e0;\n        }\n        \n        h1 {\n            text-align: center;\n            color: #222;\n            margin-bottom: 6px;\n            font-size: 18px;\n            font-weight: 600;\n        }\n        \n        .privacy-notice {\n            text-align: center;\n            font-size: 11px;\n            color: #999;\n            margin-bottom: 20px;\n        }\n        \n        .upload-section {\n            margin-bottom: 18px;\n        }\n        \n        .upload-label {\n            display: block;\n            margin-bottom: 8px;\n            font-weight: 500;\n            color: #555;\n            font-size: 12px;\n            text-transform: uppercase;\n            letter-spacing: 0.5px;\n        }\n        \n        .upload-input {\n            display: none;\n        }\n        \n        .upload-btn {\n            width: 100%;\n            padding: 10px;\n            background: #333;\n            color: white;\n            border: none;\n            border-radius: 6px;\n            font-size: 14px;\n            font-weight: 500;\n            cursor: pointer;\n            transition: background 0.2s;\n        }\n        \n        .upload-btn:hover {\n            background: #1a1a1a;\n        }\n        \n        .upload-btn:active {\n            background: #000;\n        }\n        \n        .preview-row {\n            display: grid;\n            grid-template-columns: 1fr 1fr;\n            gap: 12px;\n            margin-bottom: 18px;\n        }\n        \n        .preview-item {\n            text-align: center;\n        }\n        \n        .preview-label {\n            font-weight: 500;\n            color: #777;\n            margin-bottom: 8px;\n            display: block;\n            font-size: 11px;\n            text-transform: uppercase;\n            letter-spacing: 0.5px;\n        }\n        \n        .preview-container {\n            display: inline-block;\n            border-radius: 6px;\n            overflow: hidden;\n            background: #f9f9f9;\n            border: 1px solid #e0e0e0;\n            width: 100%;\n            max-width: 160px;\n        }\n        \n        canvas, img {\n            max-width: 100%;\n            height: auto;\n            display: block;\n            width: 100%;\n        }\n        \n        .download-btn {\n            width: 100%;\n            padding: 10px;\n            background: #4CAF50;\n            color: white;\n            border: none;\n            border-radius: 6px;\n            font-size: 14px;\n            font-weight: 500;\n            cursor: pointer;\n            transition: background 0.2s;\n        }\n        \n        .download-btn:hover {\n            background: #45a049;\n        }\n        \n        .download-btn:disabled {\n            background: #ccc;\n            cursor: not-allowed;\n        }\n        \n        .status-message {\n            text-align: center;\n            margin-top: 10px;\n            font-size: 12px;\n            color: #666;\n            min-height: 16px;\n        }\n        \n        .status-message.success {\n            color: #4CAF50;\n        }\n        \n        .status-message.error {\n            color: #d32f2f;\n        }\n    <\/style>\n<\/head>\n<body>\n    <div class=\"container\">\n        <h1>Nolympia Profilbild<\/h1>\n        <p class=\"privacy-notice\">Alle Daten werden auf deinem Ger\u00e4t verarbeitet.<\/p>\n        \n        <div class=\"upload-section\">\n            <label class=\"upload-label\">Schritt 1: Bild ausw\u00e4hlen<\/label>\n            <input \n                id=\"imageInput\" \n                type=\"file\" \n                class=\"upload-input\" \n                accept=\"image\/*\"\n            >\n            <button class=\"upload-btn\" onclick=\"document.getElementById('imageInput').click();\">\n                \ud83d\udcf8 Bild hochladen\n            <\/button>\n        <\/div>\n        \n        <div id=\"previewSection\" style=\"display: none;\">\n            <div class=\"preview-row\">\n                <div class=\"preview-item\">\n                    <label class=\"preview-label\">Original<\/label>\n                    <div class=\"preview-container\">\n                        <canvas id=\"originalCanvas\" width=\"160\" height=\"160\"><\/canvas>\n                    <\/div>\n                <\/div>\n                <div class=\"preview-item\">\n                    <label class=\"preview-label\">Mit Overlay<\/label>\n                    <div class=\"preview-container\">\n                        <canvas id=\"previewCanvas\" width=\"160\" height=\"160\"><\/canvas>\n                    <\/div>\n                <\/div>\n            <\/div>\n            \n            <button class=\"download-btn\" id=\"downloadBtn\" onclick=\"downloadImage()\">\n                \u2b07\ufe0f Herunterladen (800\u00d7800)\n            <\/button>\n            <div class=\"status-message\" id=\"statusMessage\"><\/div>\n        <\/div>\n    <\/div>\n\n    <script>\n        const overlayPath = 'https:\/\/nolympiakoeln.de\/wp-content\/uploads\/2026\/03\/olympia6.png';\n        let originalImage = null;\n        let overlayImage = null;\n        let overlayLoaded = false;\n        \n        console.log('\ud83d\ude80 Profilbild-Generator initialisiert');\n        \n        \/\/ Lade das Overlay-Bild\n        function loadOverlay() {\n            return new Promise((resolve, reject) => {\n                console.log('\ud83d\udce6 Starte Overlay-Laden...');\n                \n                overlayImage = new Image();\n                \n                overlayImage.onload = function() {\n                    overlayLoaded = true;\n                    console.log('\u2705 Overlay erfolgreich geladen:', overlayImage.width, 'x', overlayImage.height);\n                    resolve();\n                };\n                \n                overlayImage.onerror = function(err) {\n                    console.error('\u274c Overlay-Fehler beim Laden');\n                    console.error('Suchpfad:', overlayImage.src);\n                    console.error('Fehler:', err);\n                    reject(new Error('Overlay konnte nicht geladen werden'));\n                };\n                \n                \/\/ Cache-Buster: Timestamp verhindert dass alte Version aus Cache geladen wird\n                const timestamp = new Date().getTime();\n                const urlWithCache = overlayPath + '?v=' + timestamp;\n                console.log('Versuche zu laden von: ' + urlWithCache);\n                overlayImage.src = urlWithCache;\n            });\n        }\n        \n        \/\/ Warte bis die Seite vollst\u00e4ndig geladen ist, bevor wir das Overlay laden\n        window.addEventListener('load', function() {\n            console.log('\ud83d\udcc4 Seite vollst\u00e4ndig geladen');\n            \n            \/\/ Versuche das Overlay zu laden\n            loadOverlay().catch(err => {\n                console.warn('\u26a0\ufe0f Overlay beim Start nicht geladen, wird beim Bild-Upload versucht');\n            });\n            \n            \/\/ Setup Event Listener\n            const imageInput = document.getElementById('imageInput');\n            if (imageInput) {\n                imageInput.addEventListener('change', handleImageUpload);\n                console.log('\u2713 Image-Upload Listener registriert');\n            } else {\n                console.error('\u274c imageInput Element nicht gefunden!');\n            }\n        });\n        \n        \/\/ Handle Image Upload\n        function handleImageUpload(e) {\n            const file = e.target.files[0];\n            if (!file) {\n                console.log('Keine Datei ausgew\u00e4hlt');\n                return;\n            }\n            \n            console.log('\ud83d\udcf8 Bild ausgew\u00e4hlt:', file.name, file.size, 'bytes');\n            \n            const reader = new FileReader();\n            \n            reader.onload = function(event) {\n                const img = new Image();\n                \n                img.onload = function() {\n                    console.log('\u2713 Bild geladen:', img.width, 'x', img.height);\n                    originalImage = img;\n                    \n                    \/\/ Stelle sicher, dass das Overlay geladen ist\n                    if (!overlayLoaded) {\n                        console.log('Overlay noch nicht geladen, versuche jetzt...');\n                        loadOverlay().then(() => {\n                            console.log('\u2713 Overlay sp\u00e4ter erfolgreich geladen');\n                            drawPreviews();\n                            showPreview();\n                            showStatus('\u2713 Bild erfolgreich geladen', 'success');\n                        }).catch((err) => {\n                            console.error('\u26a0\ufe0f Overlay konnte nicht geladen werden:', err);\n                            drawPreviews();\n                            showPreview();\n                            showStatus('\u26a0\ufe0f Overlay konnte nicht geladen werden', 'error');\n                        });\n                    } else {\n                        console.log('\u2713 Overlay war schon vorhanden');\n                        drawPreviews();\n                        showPreview();\n                        showStatus('\u2713 Bild erfolgreich geladen', 'success');\n                    }\n                };\n                \n                img.onerror = function() {\n                    console.error('\u274c Fehler beim Laden des Bildes');\n                    showStatus('\u274c Bild konnte nicht geladen werden', 'error');\n                };\n                \n                img.src = event.target.result;\n            };\n            \n            reader.onerror = function() {\n                console.error('\u274c Fehler beim Lesen der Datei');\n                showStatus('\u274c Datei konnte nicht gelesen werden', 'error');\n            };\n            \n            reader.readAsDataURL(file);\n        }\n        \n        \/\/ Zeichne beide Vorschauen\n        function drawPreviews() {\n            if (!originalImage) {\n                showStatus('\u274c Bild nicht geladen', 'error');\n                return;\n            }\n            \n            \/\/ Zeichne Original-Vorschau\n            drawCanvasPreview(document.getElementById('originalCanvas'), originalImage, false);\n            \n            \/\/ Zeichne Preview mit Overlay\n            drawCanvasPreview(document.getElementById('previewCanvas'), originalImage, true);\n        }\n        \/\/ Zeichne auf ein Canvas - mit oder ohne Overlay\n        function drawCanvasPreview(canvas, image, withOverlay) {\n            const ctx = canvas.getContext('2d');\n            const size = canvas.width; \/\/ 160x160 f\u00fcr Vorschau\n            \n            \/\/ Berechne den Crop-Bereich (quadratisch, mittig)\n            const imgSize = Math.min(image.width, image.height);\n            const x = (image.width - imgSize) \/ 2;\n            const y = (image.height - imgSize) \/ 2;\n            \n            \/\/ F\u00fcll den Hintergrund\n            ctx.fillStyle = '#f0f0f0';\n            ctx.fillRect(0, 0, size, size);\n            \n            \/\/ Zeichne das Originalbild (quadratisch, zentriert)\n            try {\n                ctx.drawImage(\n                    image,\n                    x, y, imgSize, imgSize,\n                    0, 0, size, size\n                );\n            } catch (err) {\n                console.error('Fehler beim Zeichnen des Originalbildes:', err);\n                return;\n            }\n            \n            \/\/ Zeichne das Overlay dar\u00fcber, falls vorhanden und gew\u00fcnscht\n            if (withOverlay && overlayLoaded && overlayImage) {\n                try {\n                    ctx.drawImage(overlayImage, 0, 0, size, size);\n                } catch (err) {\n                    console.error('Fehler beim Zeichnen des Overlays:', err);\n                }\n            }\n        }\n        \n        \/\/ Erstelle Download-Canvas in voller Gr\u00f6\u00dfe\n        function getDownloadCanvas() {\n            const downloadSize = 800;\n            const canvas = document.createElement('canvas');\n            canvas.width = downloadSize;\n            canvas.height = downloadSize;\n            const ctx = canvas.getContext('2d');\n            \n            if (!originalImage) return canvas;\n            \n            \/\/ Berechne den Crop-Bereich (quadratisch, mittig)\n            const imgSize = Math.min(originalImage.width, originalImage.height);\n            const x = (originalImage.width - imgSize) \/ 2;\n            const y = (originalImage.height - imgSize) \/ 2;\n            \n            \/\/ Zeichne das Originalbild\n            ctx.drawImage(\n                originalImage,\n                x, y, imgSize, imgSize,\n                0, 0, downloadSize, downloadSize\n            );\n            \n            \/\/ Zeichne das Overlay\n            if (overlayLoaded && overlayImage) {\n                ctx.drawImage(overlayImage, 0, 0, downloadSize, downloadSize);\n            }\n            \n            return canvas;\n        }\n        \n        \/\/ Zeige die Preview-Sektion\n        function showPreview() {\n            document.getElementById('previewSection').style.display = 'block';\n        }\n        \n        \/\/ Downloade das Bild\n        function downloadImage() {\n            const canvas = getDownloadCanvas();\n            const link = document.createElement('a');\n            link.href = canvas.toDataURL('image\/png');\n            link.download = 'nolympia-profilbild.png';\n            link.click();\n            showStatus('\u2713 Download gestartet!', 'success');\n        }\n        \n        \/\/ Zeige Status-Nachricht\n        function showStatus(message, type = 'info') {\n            const statusEl = document.getElementById('statusMessage');\n            statusEl.textContent = message;\n            statusEl.className = 'status-message ' + type;\n            \n            if (type !== 'error') {\n                setTimeout(() => {\n                    statusEl.textContent = '';\n                    statusEl.className = 'status-message';\n                }, 4000);\n            }\n        }\n        \n        \/\/ Console-Log f\u00fcr Debugging\n        console.log('Profilbild-Generator initialisiert');\n    <\/script>\n<\/body>\n<\/html>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Zeig dein Nein: Dein Nolympia Profilbild! Nolympia Profilbild Alle Daten werden auf deinem Ger\u00e4t verarbeitet. Schritt 1: Bild ausw\u00e4hlen \ud83d\udcf8 Bild hochladen Original Mit Overlay \u2b07\ufe0f Herunterladen (800\u00d7800)<\/p>\n","protected":false},"author":3,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-244","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.0 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Profilbild-Generator - NOlympia K\u00f6ln<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/nolympiakoeln.de\/index.php\/profilbild-generator\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Profilbild-Generator - NOlympia K\u00f6ln\" \/>\n<meta property=\"og:description\" content=\"Zeig dein Nein: Dein Nolympia Profilbild! Nolympia Profilbild Alle Daten werden auf deinem Ger\u00e4t verarbeitet. Schritt 1: Bild ausw\u00e4hlen \ud83d\udcf8 Bild hochladen Original Mit Overlay \u2b07\ufe0f Herunterladen (800\u00d7800)\" \/>\n<meta property=\"og:url\" content=\"https:\/\/nolympiakoeln.de\/index.php\/profilbild-generator\/\" \/>\n<meta property=\"og:site_name\" content=\"NOlympia K\u00f6ln\" \/>\n<meta property=\"article:modified_time\" content=\"2026-03-21T14:52:57+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/nolympiakoeln.de\/index.php\/profilbild-generator\/\",\"url\":\"https:\/\/nolympiakoeln.de\/index.php\/profilbild-generator\/\",\"name\":\"Profilbild-Generator - NOlympia K\u00f6ln\",\"isPartOf\":{\"@id\":\"https:\/\/nolympiakoeln.de\/#website\"},\"datePublished\":\"2026-03-21T14:33:16+00:00\",\"dateModified\":\"2026-03-21T14:52:57+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/nolympiakoeln.de\/index.php\/profilbild-generator\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/nolympiakoeln.de\/index.php\/profilbild-generator\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/nolympiakoeln.de\/index.php\/profilbild-generator\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Start\",\"item\":\"https:\/\/nolympiakoeln.de\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Profilbild-Generator\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/nolympiakoeln.de\/#website\",\"url\":\"https:\/\/nolympiakoeln.de\/\",\"name\":\"NOlympia K\u00f6ln\",\"description\":\"Nein zu Olympia K\u00f6lnRheinRuhr\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/nolympiakoeln.de\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Profilbild-Generator - NOlympia K\u00f6ln","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/nolympiakoeln.de\/index.php\/profilbild-generator\/","og_locale":"de_DE","og_type":"article","og_title":"Profilbild-Generator - NOlympia K\u00f6ln","og_description":"Zeig dein Nein: Dein Nolympia Profilbild! Nolympia Profilbild Alle Daten werden auf deinem Ger\u00e4t verarbeitet. Schritt 1: Bild ausw\u00e4hlen \ud83d\udcf8 Bild hochladen Original Mit Overlay \u2b07\ufe0f Herunterladen (800\u00d7800)","og_url":"https:\/\/nolympiakoeln.de\/index.php\/profilbild-generator\/","og_site_name":"NOlympia K\u00f6ln","article_modified_time":"2026-03-21T14:52:57+00:00","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/nolympiakoeln.de\/index.php\/profilbild-generator\/","url":"https:\/\/nolympiakoeln.de\/index.php\/profilbild-generator\/","name":"Profilbild-Generator - NOlympia K\u00f6ln","isPartOf":{"@id":"https:\/\/nolympiakoeln.de\/#website"},"datePublished":"2026-03-21T14:33:16+00:00","dateModified":"2026-03-21T14:52:57+00:00","breadcrumb":{"@id":"https:\/\/nolympiakoeln.de\/index.php\/profilbild-generator\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/nolympiakoeln.de\/index.php\/profilbild-generator\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/nolympiakoeln.de\/index.php\/profilbild-generator\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Start","item":"https:\/\/nolympiakoeln.de\/"},{"@type":"ListItem","position":2,"name":"Profilbild-Generator"}]},{"@type":"WebSite","@id":"https:\/\/nolympiakoeln.de\/#website","url":"https:\/\/nolympiakoeln.de\/","name":"NOlympia K\u00f6ln","description":"Nein zu Olympia K\u00f6lnRheinRuhr","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/nolympiakoeln.de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"}]}},"_links":{"self":[{"href":"https:\/\/nolympiakoeln.de\/index.php\/wp-json\/wp\/v2\/pages\/244","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nolympiakoeln.de\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/nolympiakoeln.de\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/nolympiakoeln.de\/index.php\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/nolympiakoeln.de\/index.php\/wp-json\/wp\/v2\/comments?post=244"}],"version-history":[{"count":4,"href":"https:\/\/nolympiakoeln.de\/index.php\/wp-json\/wp\/v2\/pages\/244\/revisions"}],"predecessor-version":[{"id":255,"href":"https:\/\/nolympiakoeln.de\/index.php\/wp-json\/wp\/v2\/pages\/244\/revisions\/255"}],"wp:attachment":[{"href":"https:\/\/nolympiakoeln.de\/index.php\/wp-json\/wp\/v2\/media?parent=244"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}