PageSourceSearch

https://lumivo.ai/assets/PhotoCulling-C_0bFz1W.js

js lumivo.ai collected 2026-10-05 14:15:18 UTC 13,099 bytes, 2 lines download raw bytes

1import{r as n,j as e,L as W}from"./react-core-CtJOhYur.js";import{u as O,b7 as V,ae as w,J,a0 as X,bJ as L,M as G,e as Q,bI as Y,n as Z,o as M,K as E,B as C,D as ee,p as U,S as te,b2 as T,ay as se}from"./index-CPcMczU2.js";import{B as re}from"./BreadcrumbSchema-4oEA3liu.js";import{F as ae}from"./FAQSchema-cJEZRG8d.js";import{P as ne}from"./progress-BwwlOaTG.js";import{h as oe}from"./hasEnoughCredits-Cx-8hiQ3.js";import{A as le}from"./arrow-left-tDZsTtOT.js";import{m as ie}from"./framer-motion-CdTbmNa9.js";import{C as ce}from"./camera-BQywMLL2.js";import{U as R}from"./upload-CidU6WLz.js";import{R as de}from"./rotate-ccw-BU32FtYl.js";import{T as me}from"./thumbs-down-G9xvxtXc.js";import{C as ue}from"./circle-alert-RwkD1Bxb.js";import{S as he}from"./star-CIZThn2o.js";import"./image-tools-bOCyGMXp.js";import"./radix-Dp6HzbEj.js";import"./supabase-D-PrslnG.js";const $=1;function pe(){const{user:x}=O(),{credits:A}=V(),[f,a]=n.useState(!1),[v,h]=n.useState([]),[S,j]=n.useState({done:0,total:0}),u=n.useCallback(async d=>{if(!(x!=null&&x.id))return w.error("Bitte melde dich an",{operation:"AI Culling"}),null;if(d.length===0)return w.error("Bitte zuerst Fotos hochladen",{operation:"AI Culling"}),null;const B=$*d.length;if(!oe(A,B,!0,"photo-culling"))return null;a(!0),h([]),j({done:0,total:d.length});try{const i=[];for(let p=0;p<d.length;p+=10){const z=d.slice(p,p+10).map(K=>({id:K.id,imageBase64:K.imageBase64.replace(/^data:image\/\w+;base64,/,"")})),{data:y,error:I}=await J.functions.invoke("ai-photo-culling",{body:{photos:z}});if(I)throw I;Array.isArray(y==null?void 0:y.verdicts)&&(i.push(...y.verdicts),h([...i]),j({done:i.length,total:d.length}))}const N=i.filter(p=>p.recommendation==="keep").length;return X.success(`${i.length} Fotos analysiert · ${N} Keeper`),i}catch(g){return w.error((g==null?void 0:g.message)||"Unbekannter Fehler",{operation:"AI Culling"}),null}finally{a(!1)}},[x,A]),c=n.useCallback(()=>{h([]),j({done:0,total:0})},[]);return{isAnalyzing:f,verdicts:v,progress:S,analyze:u,reset:c,creditPerPhoto:$}}const F=50,xe=10*1024*1024,H=[{question:"Was macht AI Culling?",answer:"Lade bis zu 50 Fotos hoch — die KI bewertet jedes auf Schärfe, Belichtung, Komposition, Augen-offen und emotionalen Wert. Du bekommst eine Empfehlung pro Bild (Keep / Maybe / Reject) und kannst die Keeper als Liste exportieren."},{question:"Für wen ist es gemacht?",answer:"Hochzeits-, Event-, Portrait- und Familienfotografen, die nach jedem Shoot Stunden mit Kandeln verbringen. Die KI macht den ersten Pass — du bestätigst nur."},{question:"Wie viel kostet die Bewertung?",answer:"Nur 1 Credit pro Foto. 200 Hochzeitsbilder = 200 Credits. Du sparst typisch 4–8 Stunden Vorauswahl pro Shoot."},{question:"Welche Fotos werden empfohlen zu behalten?",answer:"Bilder mit overall-Score ≥ 75 ODER mit besonderem emotionalen Moment (key_moment, candid_moment) — auch wenn technisch nicht perfekt."},{question:"Werden meine Fotos gespeichert?",answer:"Nein. Bilder werden ausschließlich für die Bewertung an die KI übertragen und nicht persistiert."}],ge={keep:{label:"Keep",color:"bg-emerald-500/15 text-emerald-600 border-emerald-500/30",icon:he},maybe:{label:"Maybe",color:"bg-amber-500/15 text-amber-600 border-amber-500/30",icon:ue},reject:{label:"Reject",color:"bg-red-500/15 text-red-600 border-red-500/30",icon:me}};function Ee(){const x=L("/tools/ai-culling"),{user:A}=O(),f=n.useRef(null),[a,v]=n.useState([]),[h,S]=n.useState("all"),{analyze:j,isAnalyzing:u,verdicts:c,progress:d,reset:B,creditPerPhoto:g}=pe(),i=n.useMemo(()=>{const t=new Map;return c.forEach(s=>t.set(s.id,s)),t},[c]),N=n.useMemo(()=>{const t=c.filter(r=>r.recommendation==="keep").length,s=c.filter(r=>r.recommendation==="maybe").length,o=c.filter(r=>r.recommendation==="reject").length;return{keep:t,maybe:s,reject:o}},[c]),p=n.useMemo(()=>h==="all"?a:a.filter(t=>{var s;return((s=i.get(t.id))==null?void 0:s.recommendation)===h}),[a,h,i]),k=n.useCallback(t=>{const s=[];for(let r=0;r<t.length;r++){const l=t[r];l.type.startsWith("image/")&&(l.size>xe||s.push(l))}if(s.length===0){w.error("Keine gültigen Bilder gefunden",{operation:"AI Culling"});return}if(a.length+s.length>F){w.error(`Max. ${F} Fotos pro Lauf`,{operation:"AI Culling"});return}const o=s.map(r=>new Promise(l=>{const b=new FileReader;b.onload=m=>{var P,D;return l({id:`${r.name}-${r.size}-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,imageBase64:(P=m.target)==null?void 0:P.result,thumbnailUrl:(D=m.target)==null?void 0:D.result,fileName:r.name})}
1,b.readAsDataURL(r)}));Promise.all(o).then(r=>v(l=>[...l,...r]))},[a.length]),z=n.useCallback(t=>{var s;t.preventDefault(),(s=t.dataTransfer.files)!=null&&s.length&&k(t.dataTransfer.files)},[k]),y=n.useCallback(t=>{v(s=>s.filter(o=>o.id!==t))},[]),I=n.useCallback(async()=>{a.length!==0&&await j(a)},[a,j]),K=n.useCallback(()=>{v([]),B(),S("all")},[B]),q=n.useCallback(()=>{const t=a.filter(b=>{var m;return((m=i.get(b.id))==null?void 0:m.recommendation)==="keep"});if(t.length===0){w.error("Keine Keeper zum Export",{operation:"AI Culling"});return}const s=["Datei,Score,Empfehlung,Begründung,Flags"];t.forEach(b=>{const m=i.get(b.id);s.push(`"${b.fileName}",${m.overallScore},${m.recommendation},"${m.reason.replace(/"/g,"'")}","${m.flags.join("; ")}"`)});const o=new Blob([s.join(`
2`)],{type:"text/csv;charset=utf-8"}),r=URL.createObjectURL(o),l=document.createElement("a");l.href=r,l.download="ai-culling-keepers.csv",l.click(),URL.revokeObjectURL(r)},[a,i]),_=a.length*g;return e.jsxs(G,{children:[e.jsx(Q,{title:"AI Culling – Beste Fotos automatisch auswählen | Lumivo AI",description:"Spar Stunden bei der Foto-Vorauswahl: KI bewertet Schärfe, Komposition und Emotion. Top-Bilder markiert, Ausschuss aussortiert. 1 Credit pro Foto.",canonicalUrl:x,keywords:["AI Culling","Foto Vorauswahl KI","Hochzeitsfotos sortieren","Foto Bewertung KI","Best of Fotos automatisch"]}),e.jsx(re,{items:[{name:"Start",url:Y()},{name:"Tools",url:L("/tools")},{name:"AI Culling",url:x}]}),e.jsx(ae,{faqs:H}),e.jsxs("div",{className:"container mx-auto px-4 pt-24 pb-16 md:pt-28 max-w-6xl",children:[e.jsx("div",{className:"flex items-center gap-2 text-sm text-muted-foreground mb-6",children:e.jsxs(W,{to:"/tools",className:"hover:text-foreground inline-flex items-center gap-1",children:[e.jsx(le,{className:"w-3.5 h-3.5"})," Alle Tools"]})}),e.jsxs(ie.header,{initial:{opacity:0,y:16},animate:{opacity:1,y:0},className:"text-center mb-10",children:[e.jsxs(Z,{variant:"secondary",className:"mb-4 inline-flex items-center gap-1.5",children:[e.jsx(ce,{className:"w-3.5 h-3.5"})," Für Fotografen"]}),e.jsxs("h1",{className:"text-3xl md:text-5xl font-bold tracking-tight mb-4",children:["AI ",e.jsx("span",{className:"gradient-text",children:"Culling"})," — Best of automatisch"]}),e.jsx("p",{className:"text-muted-foreground text-base md:text-lg max-w-2xl mx-auto",children:"Lade 200 Hochzeitsbilder hoch — KI bewertet Schärfe, Augen-offen, Komposition und emotionalen Moment. Du sparst 4–8 Stunden pro Shoot."}),e.jsxs("div",{className:"flex flex-wrap items-center justify-center gap-4 mt-6 text-sm text-muted-foreground",children:[e.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[e.jsx(M,{className:"w-4 h-4 text-primary"})," Bis zu ",F," Fotos"]}),e.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[e.jsx(M,{className:"w-4 h-4 text-primary"})," Keep / Maybe / Reject"]}),e.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[e.jsx(M,{className:"w-4 h-4 text-primary"})," ",g," Credit pro Foto"]})]})]}),a.length===0&&e.jsx(E,{className:"p-4 md:p-6 bg-card/50 backdrop-blur mb-6",children:e.jsxs("div",{onDragOver:t=>t.preventDefault(),onDrop:z,onClick:()=>{var t;return(t=f.current)==null?void 0:t.click()},className:"border-2 border-dashed border-border hover:border-primary/60 hover:bg-primary/5 transition-colors rounded-xl flex flex-col items-center justify-center text-center p-12 cursor-pointer min-h-[280px]",children:[e.jsx(R,{className:"w-12 h-12 text-muted-foreground mb-4"}),e.jsx("h3",{className:"text-lg font-semibold mb-2",children:"Fotos hochladen"}),e.jsxs("p",{className:"text-sm text-muted-foreground max-w-md mb-4",children:["Drag & Drop mehrerer Fotos oder klicken. JPG, PNG, WEBP — max. ",F," Bilder à 10 MB."]}),e.jsxs(C,{variant:"secondary",size:"sm",children:[e.jsx(R,{className:"w-4 h-4 mr-2"})," Bilder auswählen"]}),e.jsx("input",{ref:f,type:"file",accept:"image/*",multiple:!0,className:"hidden",onChange:t=>{t.target.files&&k(t.target.files),t.target.value=""}})]})}),a.length>0&&e.jsxs(e.Fragment,{children:[e.jsxs(E,{className:"p-4 mb-4 bg-card/50 backdrop-blur",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsx("div",{className:"flex items-center gap-3",children:e.jsxs("div",{className:"text-sm",children:[e.jsx("span",{className:"font-semibold",children:a.length})," Fotos",c.length>0&&e.jsxs("span",{className:"text-muted-foreground",children:[" · ",e.jsxs("span",{className:"text-emerald-600",children:[N.keep," Keep"]})," · ",e.jsxs("span",{className:"text-amber-600",children:[N.maybe," Maybe"]})," · ",e.jsxs("span",{className:"text-red-600",children:[N.reject," Reject"]})]})]})}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs(C,{variant:"outline",size:"sm",onClick:()=>{var t;return(t=f.current)==null?void 0:t.click()},disabled:u||a.length>=F,children:[e.jsx(R,{className:"w-4 h-4 mr-2"})," Mehr hinzufügen"]}),e.jsx("input",{ref:f,type:"file",accept:"image/*",multiple:!0,className:"hidden",onChange:t=>{t.target.files&&k(t.target.files),t.target.value=""}}),c.length>0&&N.keep>0&&e.jsxs(C,{variant:"outline",size:"sm",onClick:q,children:[e.jsx(ee,{className:"w-4 h-4 mr-2"})," Keeper als CSV"]}),e.jsxs(C,{variant:"ghost",size:"sm",onClick:K,disabled:u,children:[e.jsx(de,{className:"w-4 h-4 mr-2"})," Neu starten"]}),e.jsx(C,{onClick:I,disabled:u||a.length===0||!A,size:"sm",children:u?e.jsxs(e.Fragment,{children:[e.jsx(U,{className:"w-4 h-4 mr-2 animate-spin"})," Analysiere…"]}):e.jsxs(e.Fragment,{children:[e.jsx(te,{className:"w-4 h-4 mr-2"})," ",a.length," bewerten (",_," Credits)"]})})]})]}),u&&e.jsxs("div",{className:"mt-3",children:[e.jsx(ne,{value:d.done/Math.max(d.total,1)*100,className:"h-1.5"}),e.jsxs("p",{className:"text-xs text-muted-foreground mt-1",children:[d.done," / ",d.total," bewertet"]})]}),c.length>0&&e.jsx("div",{className:"flex flex-wrap gap-1.5 mt-3",children:["all","keep","maybe","reject"].map(t=>e.jsx("button",{onClick:()=>S(t),className:T("text-xs px-3 py-1 rounded-full border transition-colors",h===t?"bg-primary text-primary-foreground border-primary":"bg-secondary border-border hover:border-primary/40"),children:t==="all"?"Alle":t==="keep"?"Keep":t==="maybe"?"Maybe":"Reject"},t))})]}),e.jsx("div",{className:"grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 ga
2p-3 mb-16",children:p.map(t=>{const s=i.get(t.id),o=s?ge[s.recommendation]:null,r=o==null?void 0:o.icon;return e.jsxs("div",{className:"relative rounded-lg overflow-hidden border border-border bg-card group",children:[e.jsxs("div",{className:"aspect-square bg-secondary/40 relative",children:[e.jsx("img",{src:t.thumbnailUrl,alt:t.fileName,className:"w-full h-full object-cover"}),!u&&e.jsx("button",{onClick:()=>y(t.id),className:"absolute top-1.5 right-1.5 p-1 rounded-full bg-background/80 backdrop-blur opacity-0 group-hover:opacity-100 transition-opacity hover:bg-destructive hover:text-destructive-foreground",children:e.jsx(se,{className:"w-3.5 h-3.5"})}),s&&o&&r&&e.jsxs("div",{className:T("absolute top-1.5 left-1.5 inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] font-semibold border backdrop-blur",o.color),children:[e.jsx(r,{className:"w-3 h-3"})," ",o.label]}),s&&e.jsx("div",{className:"absolute bottom-1.5 right-1.5 px-1.5 py-0.5 rounded text-[10px] font-bold bg-background/80 backdrop-blur",children:s.overallScore}),!s&&u&&e.jsx("div",{className:"absolute inset-0 bg-background/40 flex items-center justify-center",children:e.jsx(U,{className:"w-5 h-5 animate-spin text-primary"})})]}),s&&e.jsxs("div",{className:"p-2 text-[11px]",children:[e.jsx("p",{className:"line-clamp-2 text-muted-foreground leading-snug",children:s.reason}),s.flags.length>0&&e.jsx("div",{className:"flex flex-wrap gap-1 mt-1",children:s.flags.slice(0,2).map(l=>e.jsx("span",{className:"text-[9px] px-1.5 py-0.5 rounded bg-secondary border border-border",children:l},l))})]}),!s&&e.jsx("div",{className:"p-2 text-[11px] text-muted-foreground truncate",children:t.fileName})]},t.id)})})]}),e.jsxs("section",{className:"max-w-3xl mx-auto",children:[e.jsx("h2",{className:"text-2xl md:text-3xl font-bold text-center mb-8",children:"Häufige Fragen"}),e.jsx("div",{className:"space-y-3",children:H.map(t=>e.jsxs(E,{className:"p-5 bg-card/50",children:[e.jsx("h3",{className:"font-semibold mb-2",children:t.question}),e.jsx("p",{className:"text-sm text-muted-foreground leading-relaxed",children:t.answer})]},t.question))})]})]})]})}export{Ee as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.