2010-03-01 10 views
5

Ho un sacco di immagini di illustrazioni che vorrei ritagliare in una dimensione di anteprima più piccola.Che cos'è un buon algoritmo o libreria per ritagliare le immagini per evitare spazi vuoti o aree vuote?

Il problema è che voglio ritagliarli per mostrare una parte "interessante" dell'illustrazione (ad es. Evitare aree di spazio bianco).

Le immagini in genere hanno un colore piatto o una leggera sfumatura per lo sfondo. Sono per lo più opere d'arte in stile vettoriale con forme abbastanza distinte.

ecco alcuni esempi: link ;-)

Ho pensato di usare un qualche tipo di algoritmo di rilevamento funzione di immagine con una finestra scorrevole per trovare l'area con il maggior numero di funzionalità.

Sto implementando questo in PHP, ma non mi interessa implementarlo da solo se non è disponibile una libreria o un'estensione.

Idee?

+0

Queste sono le foto professionali? Se è così, controlla la regola dei terzi, dovrebbe almeno ridurre le diverse aree da "guardare". –

+0

Lo "spazio bianco" è veramente un colore a tinta unita o solo meno aree ricche di funzioni dell'immagine? – Matthew

risposta

1

Bene, si potrebbe voler prendere in considerazione solo l'utilizzo di un algoritmo di rilevamento dei fronti. Scegli l'area con il maggior numero di bordi. Dare maggiore peso ai bordi che non sono sfocati (come potrebbero essere dallo sfondo).

1

ImageMagick for PHP ha la generazione automatizzata di thumbnails. Questo SO question ha un collegamento a un operatore di ritaglio automatico ImageMagick e non ne sono sicuro, ma penso che this sia l'interfaccia di PHP ad esso.

Da the link:

bool Imagick :: trimImage (float $ fuzz)
rimuovere i bordi che sono il colore di sfondo dall'immagine.

Per maggiori "interestingness" generale, forse provare un inverso di seam carving (per trovare la più alta energia, piuttosto che basse zone di energia).

1

OK, quindi ecco quello che avrei fatto, dopo aver guardato gli esempi:

Somma tutte le righe e tutte le colonne di ogni immagine. Otterrete due array, sia simile a questo:

 /-----\ /--\ 
    _/  -- | 
___-    \_________ 

Guardando a questi array per alcune immagini, trovare una soglia adeguata (probabilmente qualcosa appena sopra lo zero). Quindi l'incrocio più a sinistra e più a destra di questa soglia è dove devi ritagliare. Spero di essere riuscito a chiarirlo abbastanza, se non lo è - chiedi!

+1

Non sommare le righe e le colonne, somma le * differenze * tra una riga/colonna e la successiva. –

1

programma A CLI utilizzando http://pecl.php.net/package/imagick:

<?php 
    dl('imagick.so'); 

    $img = new Imagick(); 
    $img->readImage($argv[1]); 

    # (* 0.0: exact match; * 1.0: crop entire image) 
    $fuzz = current($img->getQuantumRange()) * 0.25; 

    $img->trimImage($fuzz); 

    $img->writeImage($argv[2]); 
?> 

Dovrebbe funzionare abbastanza bene, fino a quando l'immagine non ha una cornice attorno al suo confine.

1

Ecco uno fairly simple approach utilizzando un filtro per il rilevamento dei bordi e quindi il ritaglio intorno al centro-di-spigolo dell'immagine per generare una miniatura. Funziona piuttosto bene sulla maggior parte delle immagini, ma non se ci sono più di un soggetto. Sono aperto a suggerimenti su altri modi di identificare i punti "interessanti" in un'immagine sorgente.

1

Drupal ha un progetto chiamato smartcrop, che ha il codice PHP per trovare l'entropia più alta e le aree "interessanti" nelle immagini. Vedi lo output examples.

Dovresti essere in grado di utilizzare le funzioni nel modulo e nella libreria anche in nessuno dei progetti Drupal.