Lokales KI-Bildstudio – Maximale Erweiterung
by BlazeKoala99674 lines24.5 KB
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Lokales KI-Bildstudio – Maximale Erweiterung</title>
<style>
:root {
--bg-color: #0b0f19;
--card-bg: #151f32;
--accent: #8b5cf6;
--accent-hover: #7c3aed;
--text-main: #f3f4f6;
--text-muted: #9ca3af;
--border: #374151;
}
body {
font-family: 'Segoe UI', system-ui, sans-serif;
background-color: var(--bg-color);
color: var(--text-main);
margin: 0;
padding: 20px;
display: flex;
flex-direction: column;
align-items: center;
min-height: 100vh;
}
.container {
max-width: 1000px;
width: 100%;
background: var(--card-bg);
padding: 30px;
border-radius: 16px;
box-shadow: 0 10px 30px rgba(0,0,0,0.5);
box-sizing: border-box;
}
h1 {
text-align: center;
margin: 0 0 5px 0;
font-size: 2.3rem;
background: linear-gradient(to right, #a78bfa, #f472b6);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.subtitle {
text-align: center;
color: var(--text-muted);
margin-bottom: 30px;
font-size: 0.95rem;
}
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 25px;
}
@media (max-width: 768px) {
.grid { grid-template-columns: 1fr; }
}
.panel {
background: #1e293b;
border: 1px solid var(--border);
padding: 20px;
border-radius: 12px;
display: flex;
flex-direction: column;
gap: 15px;
}
.panel h3 { margin-top: 0; color: #c084fc; }
select, input[type="file"], input[type="text"] {
width: 100%;
padding: 10px;
background: #0f172a;
border: 1px solid var(--border);
color: white;
border-radius: 6px;
box-sizing: border-box;
}
button {
background: var(--accent);
color: white;
font-weight: bold;
padding: 12px;
border: none;
border-radius: 6px;
font-size: 15px;
cursor: pointer;
transition: background 0.2s;
}
button:hover { background: var(--accent-hover); }
.preview-area {
margin-top: 30px;
background: #090d16;
border: 2px dashed var(--border);
border-radius: 12px;
min-height: 400px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 20px;
}
#canvasOutput {
max-width: 100%;
max-height: 500px;
border-radius: 8px;
box-shadow: 0 4px 15px rgba(0,0,0,0.6);
display: none;
}
.status-text {
color: #34d399;
font-weight: bold;
display: none;
margin-top: 10px;
}
</style>
</head>
<body>
<div class="container">
<h1>🔮 Lokales KI-Bildstudio Pro</h1>
<div class="subtitle">Hochwertige Erstellungs-AI, Upload, Bildfilter & Erweiterte Hinzufüge-KI</div>
<div class="grid">
<div class="panel">
<div style="border-bottom: 1px solid var(--border); padding-bottom: 15px;">
<h3 style="color: #3b82f6;">🎨 Hochwertiger KI-Generator</h3>
<label style="font-size: 0.9rem; color: var(--text-muted);">Was soll erstellt werden?</label>
<input type="text" id="aiGenPrompt" placeholder="z.B. 'fußball logo', 'cyber-stadt', 'galaxie', 'magisches schloss'">
<button onclick="generateWithMiniAI()" style="background: linear-gradient(to right, #3b82f6, #8b5cf6); margin-top: 10px;">High-End Bild generieren 🚀</button>
</div>
<div style="padding-top: 5px;">
<h3 style="color: #10b981; font-size: 1.1rem;">📁 Eigenes Bild hochladen</h3>
<input type="file" id="imageInput" accept="image/*" onchange="loadUserImage(event)">
</div>
</div>
<div class="panel">
<div style="border-bottom: 1px solid var(--border); padding-bottom: 15px;">
<h3 style="color: #ec4899; font-size: 1.1rem;">🤖 Farb- & Effektfilter</h3>
<input type="text" id="promptInput" placeholder="z.B. 'neongelb', 'dunkel', 'hell'">
<button onclick="executeAIPrompt()" style="background: linear-gradient(to right, #8b5cf6, #ec4899); margin-top: 8px;">Filter anwenden ✨</button>
<button onclick="removePixels()" style="background: linear-gradient(to right, #ef4444, #f59e0b); margin-top: 8px;">Schrift extrem schärfen 🔠</button>
</div>
<div>
<h3 style="color: #fbbf24; font-size: 1.1rem;">➕ Erweiterte Hinzufüge-KI</h3>
<label style="font-size: 0.9rem; color: var(--text-muted);">Objekt hinzufügen:</label>
<input type="text" id="addPromptInput" placeholder="z.B. 'feuer', 'krone', 'flügel', 'portal', 'laser'">
<button onclick="executeAddAI()" style="background: linear-gradient(to right, #f59e0b, #ef4444); margin-top: 8px;">Objekt einfügen 🌟</button>
<div style="font-size: 0.75rem; color: var(--text-muted); margin-top: 5px;">
<b>Befehle:</b> feuer, krone, flügel, portal, laser, stern, schloss, herz
</div>
</div>
</div>
</div>
<div class="preview-area">
<div id="placeholderText" style="color: var(--text-muted);">Wählen Sie links eine Aktion aus...</div>
<canvas id="canvasOutput"></canvas>
<p id="statusText" class="status-text"></p>
<button id="downloadBtn" style="display: none; margin-top: 15px; background: #10b981;" onclick="downloadCanvas()">💾 Bild lokal speichern</button>
</div>
</div>
<script>
const canvas = document.getElementById('canvasOutput');
const ctx = canvas.getContext('2d');
const placeholderText = document.getElementById('placeholderText');
const statusText = document.getElementById('statusText');
const downloadBtn = document.getElementById('downloadBtn');
let originalBackup = null;
function showStatus(text, delay = 0) {
statusText.innerText = text;
statusText.style.display = 'block';
if(delay > 0) setTimeout(() => { statusText.style.display = 'none'; }, delay);
}
// --- HOCHWERTIGE HIGH-END BILDERZEUGUNG ---
function generateWithMiniAI() {
const text = document.getElementById('aiGenPrompt').value.toLowerCase().trim();
if (!text) {
alert("Bitte gib einen Text für den Generator ein!");
return;
}
placeholderText.style.display = 'none';
canvas.style.display = 'block';
downloadBtn.style.display = 'block';
canvas.width = 800;
canvas.height = 800;
showStatus("KI generiert hochauflösendes Bild...");
if (text.includes("fußball") || text.includes("logo") || text.includes("wappen") || text.includes("schild")) {
let bgGrad = ctx.createRadialGradient(400, 400, 40, 400, 400, 520);
bgGrad.addColorStop(0, "#1e293b");
bgGrad.addColorStop(0.5, "#0f172a");
bgGrad.addColorStop(1, "#020617");
ctx.fillStyle = bgGrad;
ctx.fillRect(0, 0, 800, 800);
ctx.shadowColor = "rgba(0,0,0,0.8)";
ctx.shadowBlur = 30;
ctx.fillStyle = "#090d16";
ctx.strokeStyle = "#0284c7";
ctx.lineWidth = 12;
ctx.beginPath();
ctx.moveTo(400, 130);
ctx.lineTo(640, 210);
ctx.lineTo(640, 480);
ctx.quadraticCurveTo(640, 700, 400, 740);
ctx.quadraticCurveTo(160, 700, 160, 480);
ctx.lineTo(160, 210);
ctx.closePath();
ctx.fill();
ctx.stroke();
ctx.shadowBlur = 0;
ctx.strokeStyle = "#fbbf24";
ctx.lineWidth = 5;
ctx.beginPath();
ctx.moveTo(400, 155);
ctx.lineTo(615, 225);
ctx.lineTo(615, 470);
ctx.quadraticCurveTo(615, 665, 400, 705);
ctx.quadraticCurveTo(185, 665, 185, 470);
ctx.lineTo(185, 225);
ctx.closePath();
ctx.stroke();
let ballGrd = ctx.createRadialGradient(385, 405, 10, 400, 420, 105);
ballGrd.addColorStop(0, "#ffffff");
ballGrd.addColorStop(0.7, "#cbd5e1");
ballGrd.addColorStop(1, "#64748b");
ctx.fillStyle = ballGrd;
ctx.beginPath();
ctx.arc(400, 420, 105, 0, Math.PI * 2);
ctx.fill();
ctx.strokeStyle = "#0f172a";
ctx.lineWidth = 6;
ctx.stroke();
ctx.fillStyle = "#0f172a";
ctx.beginPath();
let rB = 38;
for(let i=0; i<5; i++) {
let angle = (i * 72 - 18) * Math.PI / 180;
let bx = 400 + rB * Math.cos(angle);
let by = 420 + rB * Math.sin(angle);
if(i === 0) ctx.moveTo(bx, by);
else ctx.lineTo(bx, by);
}
ctx.closePath();
ctx.fill();
const drawStar = (cx, cy, spikes, outerRadius, innerRadius) => {
let rot = Math.PI / 2 * 3;
let x = cx, y = cy;
let step = Math.PI / spikes;
ctx.beginPath();
ctx.moveTo(cx, cy - outerRadius);
for (let i = 0; i < spikes; i++) {
x = cx + Math.cos(rot) * outerRadius;
y = cy + Math.sin(rot) * outerRadius;
ctx.lineTo(x, y);
rot += step;
x = cx + Math.cos(rot) * innerRadius;
y = cy + Math.sin(rot) * innerRadius;
ctx.lineTo(x, y);
rot += step;
}
ctx.lineTo(cx, cy - outerRadius);
ctx.closePath();
ctx.fillStyle = "#fbbf24";
ctx.shadowColor = "#f59e0b";
ctx.shadowBlur = 10;
ctx.fill();
ctx.strokeStyle = "#d97706";
ctx.lineWidth = 2;
ctx.stroke();
ctx.shadowBlur = 0;
};
drawStar(400, 220, 5, 28, 14);
drawStar(330, 245, 5, 22, 11);
drawStar(470, 245, 5, 22, 11);
ctx.fillStyle = "#1e3a8a";
ctx.strokeStyle = "#fbbf24";
ctx.lineWidth = 4;
ctx.beginPath();
ctx.rect(240, 540, 320, 56);
ctx.fill();
ctx.stroke();
ctx.fillStyle = "#ffffff";
ctx.font = "bold 24px 'Segoe UI', sans-serif";
ctx.textAlign = "center";
ctx.fillText("CHAMPIONS FC", 400, 577);
}
else if (text.includes("galaxie") || text.includes("space") || text.includes("weltall")) {
ctx.fillStyle = "#020617";
ctx.fillRect(0, 0, 800, 800);
for (let i = 0; i < 700; i++) {
let x = Math.random() * 800;
let y = Math.random() * 800;
let radius = Math.random() * 2.5;
let alpha = Math.random();
ctx.fillStyle = Math.random() > 0.3 ? `rgba(255, 255, 255, ${alpha})` : `rgba(56, 189, 248, ${alpha})`;
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2);
ctx.fill();
}
let neb1 = ctx.createRadialGradient(350, 400, 30, 350, 400, 450);
neb1.addColorStop(0, "rgba(168, 85, 247, 0.6)");
neb1.addColorStop(0.5, "rgba(236, 72, 153, 0.3)");
neb1.addColorStop(1, "rgba(0,0,0,0)");
ctx.fillStyle = neb1;
ctx.fillRect(0, 0, 800, 800);
let neb2 = ctx.createRadialGradient(500, 450, 20, 500, 450, 380);
neb2.addColorStop(0, "rgba(59, 130, 246, 0.5)");
neb2.addColorStop(1, "rgba(0,0,0,0)");
ctx.fillStyle = neb2;
ctx.fillRect(0, 0, 800, 800);
}
else if (text.includes("schloss") || text.includes("magisch") || text.includes("burg")) {
let sky = ctx.createLinearGradient(0, 0, 0, 800);
sky.addColorStop(0, "#0f172a");
sky.addColorStop(0.5, "#3b0764");
sky.addColorStop(1, "#831843");
ctx.fillStyle = sky;
ctx.fillRect(0, 0, 800, 800);
let moon = ctx.createRadialGradient(600, 200, 10, 600, 200, 90);
moon.addColorStop(0, "#fef08a");
moon.addColorStop(1, "rgba(234, 179, 8, 0)");
ctx.fillStyle = moon;
ctx.beginPath();
ctx.arc(600, 200, 90, 0, Math.PI*2);
ctx.fill();
ctx.fillStyle = "#090d16";
ctx.fillRect(250, 450, 300, 350);
ctx.fillRect(200, 350, 80, 450);
ctx.fillRect(520, 350, 80, 450);
ctx.beginPath(); ctx.moveTo(190, 350); ctx.lineTo(240, 230); ctx.lineTo(290, 350); ctx.closePath(); ctx.fill();
ctx.beginPath(); ctx.moveTo(510, 350); ctx.lineTo(560, 230); ctx.lineTo(610, 350); ctx.closePath(); ctx.fill();
ctx.fillStyle = "#38bdf8";
ctx.shadowColor = "#38bdf8";
ctx.shadowBlur = 12;
ctx.fillRect(230, 400, 20, 40);
ctx.fillRect(550, 400, 20, 40);
ctx.fillRect(380, 520, 40, 60);
ctx.shadowBlur = 0;
}
else {
ctx.fillStyle = "#090d16";
ctx.fillRect(0, 0, 800, 800);
let xPos = 0;
while(xPos < 800) {
let w = 50 + Math.random() * 80;
let h = 300 + Math.random() * 450;
ctx.fillStyle = "#111827";
ctx.fillRect(xPos, 800 - h, w, h);
let windowColor = Math.random() > 0.5 ? "#38bdf8" : "#ec4899";
ctx.fillStyle = windowColor;
for(let fx = xPos + 10; fx < xPos + w - 10; fx += 14) {
for(let fy = 800 - h + 20; fy < 770; fy += 20) {
if(Math.random() > 0.25) {
ctx.fillRect(fx, fy, 7, 10);
}
}
}
xPos += w - 6;
}
}
originalBackup = ctx.getImageData(0, 0, canvas.width, canvas.height);
showStatus("✨ High-End Bild erfolgreich erstellt!", 2500);
}
function loadUserImage(event) {
const file = event.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = function(e) {
const img = new Image();
img.onload = function() {
placeholderText.style.display = 'none';
canvas.style.display = 'block';
downloadBtn.style.display = 'block';
const maxDim = 800;
let w = img.width;
let h = img.height;
if(w > maxDim || h > maxDim) {
if(w > h) { h = (maxDim/w)*h; w = maxDim; }
else { w = (maxDim/h)*w; h = maxDim; }
}
canvas.width = w;
canvas.height = h;
ctx.drawImage(img, 0, 0, w, h);
originalBackup = ctx.getImageData(0, 0, w, h);
showStatus("Bild erfolgreich geladen.", 2000);
}
img.src = e.target.result;
}
reader.readAsDataURL(file);
}
function executeAIPrompt() {
if (!originalBackup) {
alert("Bitte erstelle oder lade zuerst ein Bild!");
return;
}
const promptText = document.getElementById('promptInput').value.toLowerCase().trim();
if (!promptText) return;
showStatus("Wende Filter an...");
const w = originalBackup.width;
const h = originalBackup.height;
const src = originalBackup.data;
const dst = ctx.createImageData(w, h);
const isYellow = promptText.includes("gelb");
const isPink = promptText.includes("pink");
const isDark = promptText.includes("dunkel");
const isBright = promptText.includes("hell");
for (let i = 0; i < src.length; i += 4) {
let r = src[i], g = src[i+1], b = src[i+2], a = src[i+3];
let brightness = (r + g + b) / 3;
if (brightness < 120) {
if (isYellow) { r = 240; g = 255; b = 0; }
else if (isPink) { r = 255; g = 20; b = 147; }
}
if (isDark) { r *= 0.6; g *= 0.6; b *= 0.6; }
else if (isBright) { r = Math.min(255, r * 1.4); g = Math.min(255, g * 1.4); b = Math.min(255, b * 1.4); }
dst.data[i] = r; dst.data[i+1] = g; dst.data[i+2] = b; dst.data[i+3] = a;
}
ctx.putImageData(dst, 0, 0);
originalBackup = ctx.getImageData(0, 0, w, h);
showStatus("✨ Filter erfolgreich!", 2000);
}
// --- AGGRESSIVER SCHÄRFUNGS- & KANTENFILTER FÜR VERPIXELTE SCHRIFT ---
function removePixels() {
if (!originalBackup) {
alert("Bitte erstelle oder lade zuerst ein Bild!");
return;
}
showStatus("Verstärke Schrift-Kontraste und Kanten...");
const w = originalBackup.width;
const h = originalBackup.height;
const src = originalBackup.data;
const dst = ctx.createImageData(w, h);
const d = dst.data;
// Ein starker Schärfungs-Kernel mit erhöhtem Mittelwert zur Beseitigung von Pixelblöcken
const kernel = [
-1, -1, -1,
-1, 9, -1,
-1, -1, -1
];
for (let y = 1; y < h - 1; y++) {
for (let x = 1; x < w - 1; x++) {
let idx = (y * w + x) * 4;
let r = 0, g = 0, b = 0;
for (let ky = -1; ky <= 1; ky++) {
for (let kx = -1; kx <= 1; kx++) {
let nIdx = ((y + ky) * w + (x + kx)) * 4;
let weight = kernel[(ky + 1) * 3 + (kx + 1)];
r += src[nIdx] * weight;
g += src[nIdx + 1] * weight;
b += src[nIdx + 2] * weight;
}
}
// Schwellenwert-Kontrastbooster: Helle Pixel noch heller, dunkle Pixel noch dunkler machen,
// damit verpixelte Treppenstufen-Kanten bei Schrift wie richtige Linien wirken.
r = r < 100 ? r * 0.8 : Math.min(255, r * 1.2);
g = g < 100 ? g * 0.8 : Math.min(255, g * 1.2);
b = b < 100 ? b * 0.8 : Math.min(255, b * 1.2);
d[idx] = Math.min(255, Math.max(0, r));
d[idx + 1] = Math.min(255, Math.max(0, g));
d[idx + 2] = Math.min(255, Math.max(0, b));
d[idx + 3] = src[idx + 3];
}
}
for (let x = 0; x < w; x++) {
let topIdx = (0 * w + x) * 4;
let botIdx = ((h - 1) * w + x) * 4;
for(let c=0; c<4; c++) {
d[topIdx + c] = src[topIdx + c];
d[botIdx + c] = src[botIdx + c];
}
}
ctx.putImageData(dst, 0, 0);
originalBackup = ctx.getImageData(0, 0, w, h);
showStatus("✨ Schrift-Kontraste maximiert!", 2500);
}
// --- ERWEITERTE MINI-HINZUFÜGE-KI ---
function executeAddAI() {
if (!originalBackup) {
alert("Bitte erstelle oder lade zuerst ein Bild!");
return;
}
const addText = document.getElementById('addPromptInput').value.toLowerCase().trim();
if (!addText) {
alert("Bitte gib ein Objekt ein (z.B. 'feuer', 'krone', 'portal', 'laser', 'flügel')!");
return;
}
showStatus("Füge Objekt hinzu...");
ctx.putImageData(originalBackup, 0, 0);
const cx = canvas.width / 2;
const cy = canvas.height / 2;
if (addText.includes("feuer") || addText.includes("flamme")) {
let flameGrd = ctx.createRadialGradient(cx, cy + 50, 10, cx, cy, 120);
flameGrd.addColorStop(0, "#fef08a");
flameGrd.addColorStop(0.4, "#f97316");
flameGrd.addColorStop(0.8, "#ef4444");
flameGrd.addColorStop(1, "rgba(0,0,0,0)");
ctx.fillStyle = flameGrd;
ctx.beginPath();
ctx.arc(cx, cy, 120, 0, Math.PI * 2);
ctx.fill();
}
else if (addText.includes("portal") || addText.includes("magie")) {
let portal = ctx.createRadialGradient(cx, cy, 20, cx, cy, 150);
portal.addColorStop(0, "#ffffff");
portal.addColorStop(0.4, "#38bdf8");
portal.addColorStop(0.8, "#8b5cf6");
portal.addColorStop(1, "rgba(0,0,0,0)");
ctx.fillStyle = portal;
ctx.beginPath();
ctx.arc(cx, cy, 150, 0, Math.PI * 2);
ctx.fill();
}
else if (addText.includes("flügel") || addText.includes("wings")) {
ctx.fillStyle = "rgba(56, 189, 248, 0.8)";
ctx.shadowColor = "#38bdf8";
ctx.shadowBlur = 15;
ctx.beginPath();
ctx.moveTo(cx - 50, cy);
ctx.lineTo(cx - 200, cy - 120);
ctx.lineTo(cx - 150, cy + 50);
ctx.closePath();
ctx.fill();
ctx.beginPath();
ctx.moveTo(cx + 50, cy);
ctx.lineTo(cx + 200, cy - 120);
ctx.lineTo(cx + 150, cy + 50);
ctx.closePath();
ctx.fill();
ctx.shadowBlur = 0;
}
else if (addText.includes("laser") || addText.includes("strahl")) {
ctx.strokeStyle = "#ef4444";
ctx.lineWidth = 8;
ctx.shadowColor = "#ef4444";
ctx.shadowBlur = 20;
ctx.beginPath();
ctx.moveTo(0, cy - 50);
ctx.lineTo(canvas.width, cy + 100);
ctx.stroke();
ctx.shadowBlur = 0;
}
else if (addText.includes("krone")) {
ctx.fillStyle = "#fbbf24";
ctx.strokeStyle = "#b45309";
ctx.lineWidth = 3;
ctx.beginPath();
ctx.moveTo(cx - 70, cy - 80);
ctx.lineTo(cx - 90, cy - 140);
ctx.lineTo(cx - 30, cy - 100);
ctx.lineTo(cx, cy - 150);
ctx.lineTo(cx + 30, cy - 100);
ctx.lineTo(cx + 90, cy - 140);
ctx.lineTo(cx + 70, cy - 80);
ctx.closePath();
ctx.fill();
ctx.stroke();
}
else if (addText.includes("stern")) {
ctx.fillStyle = "#fbbf24";
ctx.shadowColor = "#f59e0b";
ctx.shadowBlur = 20;
ctx.beginPath();
let spikes = 5, outerRadius = 60, innerRadius = 25;
let rot = Math.PI / 2 * 3;
let x = cx, y = cy;
let step = Math.PI / spikes;
ctx.moveTo(x, y - outerRadius);
for (let i = 0; i < spikes; i++) {
ctx.lineTo(x + Math.cos(rot) * outerRadius, y + Math.sin(rot) * outerRadius);
rot += step;
ctx.lineTo(x + Math.cos(rot) * innerRadius, y + Math.sin(rot) * innerRadius);
rot += step;
}
ctx.closePath();
ctx.fill();
ctx.shadowBlur = 0;
}
else {
ctx.fillStyle = "#ec4899";
ctx.shadowColor = "#ec4899";
ctx.shadowBlur = 15;
ctx.beginPath();
ctx.arc(cx - 25, cy - 25, 35, Math.PI, 0, false);
ctx.arc(cx + 25, cy - 25, 35, Math.PI, 0, false);
ctx.lineTo(cx, cy + 50);
ctx.closePath();
ctx.fill();
ctx.shadowBlur = 0;
}
originalBackup = ctx.getImageData(0, 0, canvas.width, canvas.height);
showStatus("✨ Objekt erfolgreich hinzugefügt!", 2500);
}
function downloadCanvas() {
const link = document.createElement('a');
link.href = canvas.toDataURL('image/png');
link.download = 'ki-studio-pro.png';
link.click();
}
</script>
</body>
</html>Game Source: Lokales KI-Bildstudio – Maximale Erweiterung
Creator: BlazeKoala99
Libraries: none
Complexity: complex (674 lines, 24.5 KB)
The full source code is displayed above on this page.
Remix Instructions
To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: lokales-ki-bildstudio-100-offline-blazekoala99" to link back to the original. Then publish at arcadelab.ai/publish.