← Tutte le idee Negozi e community

App Shopify per foto prodotto con AI

Un'app per Shopify che crea e modifica in blocco le foto dei prodotti

Incasso mensile: 1215 USD (fonte indicata nella scheda)

Cosa fa

App per negozi Shopify: genera e modifica con l'AI le foto di molti prodotti insieme, per avere immagini professionali senza fotografo.

Come guadagna

Incasso annuo dichiarato di circa 14.600 $ nell'annuncio di vendita su Microns, che verifica i dati. Il nome del progetto non è pubblico.

Rendilo tuo

  • Per piattaforme meno affollate: WooCommerce, PrestaShop, molto usati in Italia.
  • Specializzata in un settore: gioielli, abbigliamento, cibo.

Le frasi da scrivere all'AI

1. Base del sito e grafica

Crea un'app web in italiano chiamata "Foto Prodotto": trasforma le foto dei prodotti scattate col telefono in immagini da negozio online: sfondo bianco pulito, ombre, ambientazioni, tutte insieme e pronte per Shopify, Amazon ed eBay. Usa React, Vite, TypeScript e Tailwind CSS.

Pagine da creare:
1. Pagina iniziale con prima/dopo e prezzi
2. Registrazione e accesso
3. Caricamento in blocco: fino a 100 foto
4. Lavorazione: scegli sfondo bianco, ambientazione o colore
5. Esportazione: zip con le foto e file CSV per l'importazione in Shopify

Stile: da e-commerce: sfondo grigio chiaro #F6F6F7, verde Shopify #008060, testo #202223, carattere "Inter", griglia di miniature con il prima e dopo al passaggio del mouse. Nessuna immagine generica di stock.

Tutto deve funzionare perfettamente da telefono. Tutti i testi in italiano, chiari e senza parole tecniche.

2. Database, account e sicurezza

Collega il progetto a Supabase e attiva la registrazione con email e password.

Crea queste tabelle:
- "lotti": nome, impostazioni (tipo di sfondo, misura, margine), collegati all'utente
- "immagini": originale e risultato nello Storage, codice prodotto (SKU), stato

Regole di sicurezza obbligatorie:
- ogni utente vede solo i suoi lotti e immagini
- i crediti non si modificano dal browser

Usa esattamente il codice SQL che trovi nei "Dettagli tecnici" di questa scheda: eseguilo nel SQL Editor di Supabase prima di continuare, poi collega le pagine alle tabelle.

3. Lavorazione in blocco

L'utente trascina fino a 100 foto e, se vuole, un CSV con nome del file e codice prodotto. Sceglie: sfondo bianco puro (per Amazon), ambientazione (cucina, scrivania, natura...) o colore pieno, misura (2000×2000 consigliata) e margine.

Per ogni foto una Edge Function scontorna il prodotto con un servizio di rimozione dello sfondo, poi lo posiziona centrato sulla tela nella misura scelta (codice nei Dettagli tecnici), con un'ombra leggera. Per le ambientazioni usa un'API di modifica immagini che non cambia il prodotto.

Una coda lavora le foto una alla volta e la pagina mostra l'avanzamento.

4. Esportazione per Shopify

Esportazione in uno zip con i file rinominati per codice prodotto, e un CSV nel formato di importazione di Shopify con il collegamento a ogni immagine (Image Src), così si caricano tutte con l'importazione prodotti.

Questa versione è un'app web indipendente: per entrare nell'App Store di Shopify servirebbero il login Shopify e i pagamenti tramite Shopify Billing, da valutare dopo.

5. Pagamenti con Stripe

Aggiungi pacchetti di crediti: 100 immagini a 12 €, 500 immagini a 45 €. Ogni nuovo utente riceve 10 crediti gratis. Ogni immagine lavorata costa un credito. Mostra sempre in alto quanti crediti restano e, quando finiscono, un riquadro per comprarne altri.

A pagamento riuscito il webhook aggiunge i crediti del pacchetto con la funzione aggiungi_crediti.

Per la sessione di pagamento e il webhook segui la guida "Pagamenti con Stripe" di Fattibile.

6. Controlli specifici di questo progetto

Oltre ai controlli della guida "Controllo finale", verifica in particolare:
1. Fedeltà: controlla su 10 prodotti diversi che il prodotto non venga deformato e che i loghi e le scritte restino identici.
Correggi quello che non va e scrivimi cosa hai cambiato.

Dettagli tecnici

Prodotto centrato su sfondo bianco

Prende il prodotto già scontornato (PNG trasparente), lo ridimensiona perché occupi l'85% della tela e lo centra su sfondo bianco puro.

export async function suSfondoBianco(scontornato: Blob, lato = 2000, occupazione = 0.85): Promise<Blob> {
  const img = await createImageBitmap(scontornato);

  // Trova il riquadro reale del prodotto (pixel non trasparenti)
  const prova = new OffscreenCanvas(img.width, img.height);
  const pctx = prova.getContext("2d")!;
  pctx.drawImage(img, 0, 0);
  const { data } = pctx.getImageData(0, 0, img.width, img.height);
  let minX = img.width, minY = img.height, maxX = 0, maxY = 0;
  for (let y = 0; y < img.height; y++) {
    for (let x = 0; x < img.width; x++) {
      if (data[(y * img.width + x) * 4 + 3] > 10) {
        if (x < minX) minX = x; if (x > maxX) maxX = x;
        if (y < minY) minY = y; if (y > maxY) maxY = y;
      }
    }
  }
  const larg = maxX - minX + 1, alt = maxY - minY + 1;
  const scala = (lato * occupazione) / Math.max(larg, alt);

  const tela = new OffscreenCanvas(lato, lato);
  const ctx = tela.getContext("2d")!;
  ctx.fillStyle = "#FFFFFF";                       // bianco puro: RGB 255,255,255
  ctx.fillRect(0, 0, lato, lato);
  ctx.drawImage(img, minX, minY, larg, alt,
    (lato - larg * scala) / 2, (lato - alt * scala) / 2, larg * scala, alt * scala);
  img.close();
  return tela.convertToBlob({ type: "image/jpeg", quality: 0.92 });
}

Lotti e immagini

I lotti di lavorazione con le loro immagini e lo stato di ognuna.

create table lotti (
  id uuid primary key default gen_random_uuid(),
  utente_id uuid not null references auth.users(id) on delete cascade,
  nome text not null,
  impostazioni jsonb not null,   -- { sfondo, lato, occupazione, ambientazione }
  creato_il timestamptz not null default now()
);

create table immagini (
  id uuid primary key default gen_random_uuid(),
  lotto_id uuid not null references lotti(id) on delete cascade,
  utente_id uuid not null references auth.users(id) on delete cascade,
  sku text,
  originale_path text not null,
  risultato_path text,
  stato text not null default 'in_attesa' check (stato in ('in_attesa', 'in_corso', 'pronta', 'errore'))
);

alter table lotti enable row level security;
create policy "le mie righe" on lotti
  for all using (auth.uid() = utente_id) with check (auth.uid() = utente_id);

alter table immagini enable row level security;
create policy "le mie righe" on immagini
  for all using (auth.uid() = utente_id) with check (auth.uid() = utente_id);

insert into storage.buckets (id, name, public) values ('prodotti', 'prodotti', false);
create policy "la mia cartella prodotti" on storage.objects for all to authenticated
  using (bucket_id = 'prodotti' and (storage.foldername(name))[1] = auth.uid()::text)
  with check (bucket_id = 'prodotti' and (storage.foldername(name))[1] = auth.uid()::text);

Pezzi comuni a tutti i progetti

Glossario

Storage
Lo spazio di Supabase dove si salvano i file, come foto e audio, con le sue regole di accesso.
CSV
Un file di testo con i dati separati da virgole, che si apre con Excel.
JSONB
Un tipo di colonna che contiene dati strutturati flessibili, come un piccolo documento.
SKU
Il codice interno che identifica ogni prodotto in un negozio.