2010-02-10 22 views
22

La mia azienda ha iniziato recentemente a riscontrare problemi con la gestione delle immagini per i nostri siti Web.Elaborazione delle immagini con ridimensionamento al volo

Abbiamo diversi siti Web (intrattenimento per adulti) che visualizzano immagini come copertine di DVD, istantanee e simili. Abbiamo circa 100.000 film e per ogni film abbiamo una media di 30 istantanee + cover. Quasi tutte le immagini hanno una versione aggiuntiva con sfocatura e sovrapposizione per i non membri, questo si traduce in circa 50 immagini per film o un totale di 5 milioni di immagini di base. Ognuna delle immagini è disponibile in diverse versioni, a seconda di dove è posizionata sulla pagina (anteprima, anteprima originale, anteprima piccola, anteprima non piccola, immagine piccola nella lista in alto, ecc.) Che si traduce in più immagini di Mi importava di contare.

Ora ho avuto l'idea di utilizzare un server per generare le immagini al volo poiché è diventato piuttosto maldestro generare tutte le diverse immagini per tutte le diverse pagine (poiché le pagine diverse a volte hanno anche bisogno di dimensioni dell'immagine diverse per fondamentalmente lo stesso compito).

Qualcuno sa di un server di elaborazione immagini in grado di ridimensionare le immagini al volo, quindi abbiamo solo bisogno di fornire le immagini originali e il web ragazzi possono solo richiedere qualsiasi dimensione di cui hanno bisogno?

Requisiti:

  • prestazioni molto elevate (migliaia di utenti al giorno)
  • on-the-fly sfocatura e la creazione di overlay
  • on-the-fly di ridimensionamento (con e senza mantenere le proporzioni)
  • in grado di gestire milioni di immagini
  • deve essere in grado di leggere JPG, GIF, PNG e BMP e la conversione tra di loro

La sicurezza non è un problema, perché le immagini non mosse possono essere raggiunte dalla manipolazione degli URL e maggiore sicurezza sarebbe buona ma non è richiesta e francamente ho smesso di preoccuparmi (dopo aver fallito nel mio teste di colleghi perché (per la nostra piccola pagina di rivenditori) è una cattiva idea usare http://example.com/view_image.php?filename=/data/images/01020304.jpg per visualizzare le immagini).

Abbiamo provato gli script PHP per farlo, ma le prestazioni erano troppo lente per molti utenti.

Grazie in anticipo per eventuali suggerimenti che avete.

+0

https://github.com/willnorris/imageproxy – wildloop

risposta

26

Suggerisco di configurare un server Web dedicato per gestire il ridimensionamento dell'immagine e servire il risultato finale. Ho fatto qualcosa di simile, anche se su scala molto più piccola. In pratica elimina il processo di verifica della cache.

funziona così:

  • di richiedere l'immagine aggiungendo la dimensione necessaria per il nome del file come http://imageserver/someimage.150x120.jpg
  • se esiste l'immagine, che verrà restituita con nessun altro trattamento (questo è il punto principale , il controllo di cache è implicita)
  • se l'immagine non esiste, di gestire il 404 non trovato tramite .htaccess e reindirizzare la richiesta allo script che genera l'immagine della dimensione richiesta
  • nello script specificare l'elenco di dimensioni consentite per evitare attacchi come gli script che richiedono ogni misura possibile per arrestare il server verso il basso
  • tenere questo in un dominio senza cookie per ridurre al minimo il traffico non necessario

EDIT: Non credo che lo stesso PHP rallenterebbe il processo molto, come Lo scripting PHP in questo caso è ridotto al minimo: lo scaling dell'immagine è fatto da una libreria incorporata scritta in C. Qualunque cosa tu faccia, dovrai usare una libreria come questa (GD o libmagick o così), quindi è inevitabile. Con il mio sistema, almeno, salti totalmente il sovraccarico di controllare la cache, riducendo ulteriormente l'interazione con PHP. Puoi implementarlo sul tuo server esistente, quindi suppongo che sia una soluzione adatta al tuo budget.

+0

Buon suggerimento, controllerò se è possibile implementarlo senza un server web aggiuntivo in quanto non saremo in grado di ottenerne uno per questo. – dbemerlin

+0

È totalmente possibile, ho suggerito il server dedicato solo per condividere il carico. In ogni caso, anche su un singolo server, considera l'utilizzo di un host virtuale diverso per l'ultimo punto che ho menzionato –

+0

. Sto accettando questa soluzione ora poiché sembra essere la soluzione che si adatta meglio con il minimo sovraccarico, ora devo solo ottenere fino alla gestione. – dbemerlin

7

Sulla base

Abbiamo provato script PHP per farlo, ma la prestazione è stata troppo lenta per questo molti utenti.

Presumo che non stiate memorizzando i risultati nella cache. Suggerirei di memorizzare nella cache le immagini risultanti per un giorno o due (ad esempio, controllare lo script per vedere se la miniatura è già stata generata, in tal caso usarla, se non è stata generata al volo).

Ciò migliorerebbe notevolmente le prestazioni poiché immagino che la pagina principale/iniziale abbia probabilmente più hit rispetto al video casuale X, quindi durante la visualizzazione della pagina principale non è necessario creare immagini mentre vengono memorizzate nella cache. Quando l'utente Y visualizza Film X, non noterà il ritardo tanto quanto deve generare quella pagina.

Per l'aspetto "Ridimensiona al volo": quanto è importante la larghezza di banda?Vorrei presumere che tu stia attraversando così tanto con i film che qualche kb in più in immagini per richiesta non farebbe troppi danni. In questo caso, puoi semplicemente utilizzare immagini più grandi e impostare la larghezza e l'altezza e lasciare che il browser esegua il ridimensionamento.

+4

Anche meglio di caching in locale ... richiedere le immagini tramite un CDN e poi il CDN memorizza nella cache tutti i generato immagini per te e servirle molto più velocemente di quanto puoi, con costi di larghezza di banda più bassi. È così che lo facciamo ed è estremamente efficace. –

+0

+1 Assolutamente secondo! Perché creare un server on-the-cost costoso quando è possibile ottenere ciò che è necessario con gli strumenti domestici. –

+0

@Greg Beech: potrebbe essere difficile trovare un CDN che sarà felice di memorizzare nella cache questo tipo di file. – cherouvim

4

I ImageCache e Image Exact Sizes soluzioni dalla Drupal comunità potrebbero fare questo, e come la maggior parte delle soluzioni OSS utilizzare le librerie da ImageMagik

Ci sono alcune immagini AMI per il servizio EC2 Amazzoni da fare una scalatura delle immagini. Ha utilizzato Amazon S3 per l'archiviazione di immagini, originali e scalabili e li ha potuti fornire tramite il servizio CDN di Amazons (Cloud Front). Controlla sul sito EC2 per cosa è disponibile

Un'altra opzione è Google. Google Documenti ora supporta tutti i tipi di file, quindi puoi caricare le immagini in una cartella di Google Documenti e condividere la cartella per l'accesso pubblico. Gli URL sono di tipo lungo ad es.

http://lh6.ggpht.com/VMLEHAa3kSHEoRr7AchhQ6HEzHVTn1b7Mf-whpxmPlpdrRfPW216UhYdQy3pzIe4f8Q7PKXN79AD4eRqu1obC7I

Aggiungere i = s paramter per scalare l'immagine, cool! per esempio. per 200 pixel di larghezza

http://lh6.ggpht.com/VMLEHAa3kSHEoRr7AchhQ6HEzHVTn1b7Mf-whpxmPlpdrRfPW216UhYdQy3pzIe4f8Q7PKXN79AD4eRqu1obC7I=s200

Google carica solo USD5/anno per il 20GB. V'è un'API completo per documenti caricamento ecc

Altre risposte su SO How best to resize images off-server

+0

Grazie per il buon suggerimento, ma un fornitore esterno non è (purtroppo) un'opzione (la direzione non lo approverà, abbiamo già provato a ottenere qualcosa di simile attraverso) – dbemerlin

+0

bel suggerimento! questa tecnica può essere utilizzata per supportare altezza e larghezza esatte? \ – DjangoRocks

1

Ok primo problema è che il ridimensionamento di un'immagine con qualsiasi linguaggio prende un po 'di tempo di elaborazione. Quindi, come supporti migliaia di clienti? Lo memorizzeremo nella cache in modo da generare l'immagine solo una volta. La prossima volta che qualcuno chiede quell'immagine, controlla se è già stata generata, se ha appena restituito quella immagine. Se disponi di più server di app, ti consigliamo di effettuare il cache in un sistema di file centrale per aumentare il tuo rapporto cache-hit e ridurre la quantità di spazio che ti servirà.

Al fine di memorizzare nella cache correttamente è necessario utilizzare una convenzione di denominazione prevedibile che tenga conto di tutti i diversi modi in cui si desidera la vostra immagine visualizzata, cioè usare qualcosa come myimage_blurred_320x200.jpg per salvare un jpeg che è stata offuscata e ridimensionata per 300 larghezza e 200 altezza, ecc.

Un altro approccio consiste nel posizionare il server di immagini dietro un server proxy in questo modo tutta la logica di memorizzazione nella cache viene eseguita automaticamente per te e le immagini sono servite da un server web veloce nativo.

Il tuo non sarà in grado di servire milioni di immagini ridimensionate in altro modo. È così che le mappe di Google e Bing lo fanno, pre-generano tutte le immagini di cui hanno bisogno per il mondo a diverse estensioni preimpostate in modo che possano fornire prestazioni adeguate ed essere in grado di restituire immagini statiche pre-generate.

Se php è troppo lento, è consigliabile utilizzare le librerie grafiche 2D da Java o .NET poiché sono molto ricche e in grado di supportare tutte le esigenze. Per avere un'idea dell'API di grafica, ecco un metodo in .NET che ridimensionerà qualsiasi immagine alla nuova larghezza o altezza specificata. Se si omette l'altezza o la larghezza, verrà ridimensionato mantenendo le giuste proporzioni. Nota immagine può essere un creato da un JPG, GIF, PNG o BMP:

// Creates a re-sized image from the SourceFile provided that retails the same aspect ratio of the SourceImage. 
// - If either the width or height dimensions is not provided then the resized image will use the 
//  proportion of the provided dimension to calculate the missing one. 
// - If both the width and height are provided then the resized image will have the dimensions provided 
//  with the sides of the excess portions clipped from the center of the image. 
public static Image ResizeImage(Image sourceImage, int? newWidth, int? newHeight) 
{ 
    bool doNotScale = newWidth == null || newHeight == null; ; 

    if (newWidth == null) 
    { 
     newWidth = (int)(sourceImage.Width * ((float)newHeight/sourceImage.Height)); 
    } 
    else if (newHeight == null) 
    { 
     newHeight = (int)(sourceImage.Height * ((float)newWidth)/sourceImage.Width); 
    } 

    var targetImage = new Bitmap(newWidth.Value, newHeight.Value); 

    Rectangle srcRect; 
    var desRect = new Rectangle(0, 0, newWidth.Value, newHeight.Value); 

    if (doNotScale) 
    { 
     srcRect = new Rectangle(0, 0, sourceImage.Width, sourceImage.Height); 
    } 
    else 
    { 
     if (sourceImage.Height > sourceImage.Width) 
     { 
      // clip the height 
      int delta = sourceImage.Height - sourceImage.Width; 
      srcRect = new Rectangle(0, delta/2, sourceImage.Width, sourceImage.Width); 
     } 
     else 
     { 
      // clip the width 
      int delta = sourceImage.Width - sourceImage.Height; 
      srcRect = new Rectangle(delta/2, 0, sourceImage.Height, sourceImage.Height); 
     } 
    } 

    using (var g = Graphics.FromImage(targetImage)) 
    { 
     g.SmoothingMode = SmoothingMode.HighQuality; 
     g.InterpolationMode = InterpolationMode.HighQualityBicubic; 

     g.DrawImage(sourceImage, desRect, srcRect, GraphicsUnit.Pixel); 
    } 

    return targetImage; 
} 
+0

Grazie per i suggerimenti e il codice, lo valuterò e controllerò se potrebbe essere abbastanza veloce (e creerò anche un benchmark PHP, per verificare se il mio i colleghi avevano ragione con "PHP è troppo lento"). – dbemerlin

0

Se ogni immagine diversa è identificabile in modo univoco da un singolo URL poi mi è sufficiente utilizzare un CDN, come AKAMAI. Lascia che lo script PHP faccia il lavoro e lascia che AKAMAI gestisca il carico.

Dal momento che questo tipo di attività di solito non ha problemi di budget, quello sarebbe l'unico posto dove guarderei.

Modifica: funziona solo se trovi una CDN che servirà questo tipo di contenuti per te.

+0

Devo scartare questa soluzione perché il budget disponibile è esattamente 0 Euro (o per voi gente USA: esattamente $ 0). Non siamo nemmeno riusciti a far sì che il management approvasse l'installazione di un server di test o di sviluppo (ma che ora ci vuole il doppio del tempo per svilupparlo non è un problema perché gli sviluppatori non costano nulla visto che sono già lì ...). Comunque, grazie per il tuo suggerimento. – dbemerlin

+0

Un server di immagini dedicato E una rete CND possono funzionare bene insieme. Prendi il carico dal tuo sito principale e le immagini verranno comunque consegnate molto velocemente in tutto il mondo. – adrianTNT

1

Nel tempo in cui è stata posta questa domanda, alcune società sono sorte per affrontare questo problema. Non è un problema isolato per te o la tua azienda. Molte aziende raggiungono il punto in cui hanno bisogno di cercare una soluzione più permanente per le loro esigenze di elaborazione delle immagini.

Servizi come imgix fungono da proxy e CDN per operazioni di immagine come il ridimensionamento e l'applicazione di sovrapposizioni. Manipolando l'URL, puoi applicare diverse trasformazioni a ciascuna immagine. imgix serve miliardi di richieste al giorno.

È inoltre possibile gestire autonomamente i servizi e inserirli dietro un CDN. Progetti open source come imageproxy vanno bene per questo. Ciò pone l'onere della manutenzione sul team operativo.

(Disclaimer:. Io lavoro per imgix)

1

Quello che state cercando è meglio accompagnato da Thumbor http://thumbor.readthedocs.org/en/latest/index.html, che è open source, sostenuta da una grande azienda (significa che non scomparirà domani), e le navi con molte funzioni interessanti come la rilevazione di ciò che è importante su un'immagine al momento del ritaglio.

Per CDN a basso costo e suggerirei di combinarlo con lo storage Cloudfront e AWS o una soluzione comparabile con un CDN gratuito come Cloudflare. Questi potrebbero non essere i migliori fornitori di CDN, ma almeno hanno prestazioni migliori di un server e anche il tuo server di immagini a basso costo. Inoltre, ti farà risparmiare un tonnellata di costo della larghezza di banda.

0

Questo stesso identico problema è ora risolto dai servizi di ridimensionamento delle immagini dedicati a questa attività. Essi forniscono seguenti caratteristiche:

  1. integrato CDN - non è necessario preoccuparsi circa la distribuzione delle immagini
  2. immagine ridimensionare al volo - qualsiasi dimensione necessaria è disponibile
  3. No storage necessaria - basta immagine del punto vendita di base e tutti le varianti sono gestite dal servizio
  4. Librerie di ecosistemi - puoi semplicemente includere javascript e il tuo lavoro è fatto per tutti i dispositivi e tutti i browser.

Uno di questi è il servizio Gumlet. Puoi anche provare qualche alternativa open source come il plugin nginx che può anche ridimensionare l'immagine al volo.

(Lavoro per Gumlet.)

Problemi correlati