2010-02-10 19 views
22

mi empresa ha empezado recientemente a tener problemas con el manejo de imágenes para nuestros sitios web.Sirviendo imágenes con el cambio de tamaño en el terreno

Tenemos varios sitios web (entretenimiento para adultos) que muestran imágenes como portadas de dvd, instantáneas y similares. Tenemos aproximadamente 100'000 películas y para cada película tenemos un promedio de 30 instantáneas + portadas. Casi todas las imágenes tienen una versión adicional con borrosidad y superposición para los que no son miembros, esto da como resultado aproximadamente 50 imágenes por película o un total de 5 millones de imágenes base. Cada una de las imágenes está disponible en varias versiones, dependiendo de dónde se coloca en la página (miniatura, original, vista previa pequeña, vista previa no tan pequeña, imagen pequeña en la lista superior, etc.) que da como resultado más imágenes que Me importaba contar

Ahora tuve la idea de usar un servidor para generar las imágenes sobre la marcha ya que se volvió bastante torpe generar todas las diferentes imágenes para las diferentes páginas (como diferentes páginas a veces incluso necesitan diferentes tamaños de imagen para básicamente la misma tarea).

¿Alguien sabe de un servidor de procesamiento de imágenes que puede reducir las imágenes al vuelo, por lo que solo tenemos que proporcionar las imágenes originales y los usuarios de la web solo pueden solicitar el tamaño que necesiten?

Requisitos:

  • rendimiento muy alto (varios miles de usuarios por día)
  • on-the-fly distorsión y la creación de superposición
  • En la marcha de cambio de tamaño (con y sin relación de aspecto de mantenimiento)
  • Se puede manejar millones de imágenes
  • debe ser capaz de leer JPG, GIF, PNG y BMP y convertir entre ellos

La seguridad no es tan preocupante ya que las imágenes no difuminadas ya pueden ser alcanzadas por la manipulación de URL y más seguridad sería agradable pero no es necesaria y francamente dejé de preocuparme (después de no poder hablar con mis colegas, nuestra pequeña página de revendedores) es una mala idea usar http://example.com/view_image.php?filename=/data/images/01020304.jpg para mostrar las imágenes).

Probamos los scripts PHP para hacer esto pero el rendimiento fue demasiado lento para muchos usuarios.

Gracias de antemano por cualquier sugerencia que tenga.

+0

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

Respuesta

26

Le sugiero que configure un servidor web dedicado para manejar el tamaño de la imagen y servir el resultado final. He hecho algo similar, aunque en una escala mucho más pequeña. Básicamente, elimina el proceso de comprobación de la memoria caché.

funciona así:

  • usted solicite la imagen añadiendo el tamaño requerido para el nombre de fichero como http://imageserver/someimage.150x120.jpg
  • si existe la imagen, se le devolverá sin otro procesamiento (este es el punto principal , la comprobación de caché está implícita)
  • si la imagen no existe, gestione el 404 no encontrado mediante .htaccess y redireccione la solicitud al script que genera la imagen del tamaño requerido
  • en el script especifique la lista de tamaños permitidos para evitar ataques como las secuencias de comandos que solicitan todos los tamaños posible cerrar un poco el servidor
  • mantener esto en un dominio sin cookies para reducir al mínimo el tráfico innecesario

EDIT: No creo que el propio PHP frenaría el proceso mucho más, como Las secuencias de comandos PHP en este caso se reducen al mínimo: la escala de la imagen se realiza mediante una biblioteca integrada escrita en C. Hagas lo que hagas, tendrás que usar una biblioteca como esta (GD o libmagick más o menos), por lo que es inevitable. Con mi sistema, al menos, omite por completo la sobrecarga de verificar el caché, lo que reduce aún más la interacción de PHP. Puede implementar esto en su servidor existente, así que supongo que es una solución adecuada para su presupuesto.

+0

Buena sugerencia, verificaré si es posible implementar esto sin un servidor web adicional, ya que no podremos obtener uno para esto. – dbemerlin

+0

Es totalmente posible, sugerí el servidor dedicado solo para compartir la carga. En cualquier caso, incluso en un solo servidor, considere usar un host virtual diferente para el último punto que mencioné –

+0

. Estoy aceptando esta solución ahora, ya que parece ser la solución que se escala mejor con el mínimo gasto, ahora solo tengo que obtener a través de la gestión. – dbemerlin

7

Basado en

Probamos scripts PHP para hacer esto, pero el rendimiento era demasiado lento para esto muchos usuarios.

Voy a suponer que no estaba almacenando en caché los resultados. Recomiendo guardar en caché las imágenes resultantes durante uno o dos días (es decir, hacer que el script se compruebe para ver si la miniatura ya se ha generado, de ser así, usarla, si no la ha generado al vuelo).

Esto mejoraría dramáticamente el rendimiento ya que me imagino que la página principal/de inicio probablemente tiene muchas más visitas que el video X aleatorio, por lo tanto al visualizar la página principal no se deben crear imágenes mientras están en la memoria caché. Cuando el usuario Y ve la película X, no notarán la demora, ya que solo tiene que generar esa página.

Para el aspecto de "cambio de tamaño en la marcha", ¿qué importancia tiene para ti el ancho de banda?Me gustaría asumir que estás pasando por muchas películas que algunos kb adicionales en imágenes por solicitud no causarían demasiado daño. Si ese es el caso, podría simplemente usar imágenes más grandes y establecer el ancho y alto y dejar que el navegador haga la escala por usted.

+4

Incluso mejor que el almacenamiento en caché de forma local ... solicitar las imágenes a través de un CDN y luego el CDN depositará toda la generaron imágenes para usted y las sirve mucho más rápido que usted, con costos de banda ancha más baratos. Así es como lo hacemos y es extremadamente efectivo. –

+0

+1 Estoy en segundo lugar! ¿Por qué configurar un servidor on-the-fly costoso cuando lo que necesita se puede lograr con herramientas domésticas? –

+0

@Greg Beech: puede ser difícil encontrar un CDN que con gusto guarde en caché este tipo de archivos. – cherouvim

4

Los ImageCacheImage Exact Sizes y soluciones de la comunidad Drupalpodrían hacer esto, y como la mayoría de las soluciones OSS utilizar las bibliotecas de ImageMagik

Hay algunas imágenes para el servicio AMI Amazonas EC2 que hacer escala de imagen. Usó Amazon S3 para el almacenamiento de imágenes, original y escalas, y podría alimentarlos a través del servicio Amazons CDN (Cloud Front). Consulte en el sitio de EC2 qué hay disponible

Otra opción es Google. Los documentos de Google ahora son compatibles con todos los tipos de archivos, por lo que puede cargar las imágenes en una carpeta de documentos de Google y compartir la carpeta para el acceso público. Las URL son algo largas, p.

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

Añadir los s = Parámetro para escalar la imagen, fresco! p.ej. por 200 píxeles de ancho

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

Google único cargo de 5 dólares/año por 20 GB. Hay una API completa para subir documentos, etc

Otras respuestas sobre SO How best to resize images off-server

+0

Gracias por la buena sugerencia, pero un proveedor externo no es (lamentablemente) una opción (la administración no lo aprobará, ya tratamos de obtener algo similar) – dbemerlin

+0

nice suggestion! ¿Se puede usar esta técnica para soportar la altura y el ancho exactos? \ – DjangoRocks

1

Ok primer problema es que el cambio de tamaño de una imagen con cualquier lenguaje toma un poco de tiempo de procesamiento. Entonces, ¿cómo ayudas a miles de clientes? Lo almacenaremos en la memoria caché para que solo tenga que generar la imagen una vez. La próxima vez que alguien solicite esa imagen, verifique si ya se ha generado, si acaba de devolverla. Si tiene varios servidores de aplicaciones, querrá guardarlos en un sistema de archivos central para aumentar la proporción de aciertos de caché y reducir la cantidad de espacio que necesitará.

Para caché correctamente, debe usar una convención de nomenclatura predecible que tenga en cuenta todas las formas en que desea que se muestre su imagen, es decir, utilice algo como myimage_blurred_320x200.jpg para guardar un jpeg borroso y redimensionado a 300 ancho y 200 alto, etc.

Otro enfoque es ubicar su servidor de imágenes detrás de un servidor proxy de esa manera toda la lógica de almacenamiento en caché se realiza automáticamente y un servidor web rápido y nativo sirve las imágenes.

No va a poder servir millones de imágenes redimensionadas de ninguna otra manera. Así es como lo hacen los mapas de Google y Bing, pregeneran todas las imágenes que necesitan para el mundo en diferentes extensiones preestablecidas para que puedan proporcionar el rendimiento adecuado y poder devolver imágenes estáticas pregeneradas.

Si php es demasiado lento, debería considerar utilizar las librerías de gráficos 2D de Java o .NET, ya que son muy completas y pueden satisfacer todas sus necesidades. Para obtener un sabor de la API de gráficos, aquí hay un método en .NET que redimensionará cualquier imagen al nuevo ancho o alto especificado. Si omites una altura o un ancho, cambiará el tamaño manteniendo la relación de aspecto correcta. Nota imagen puede ser un crea a partir de un archivo 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

Gracias por las sugerencias y el código, lo compararé y verificará si puede ser lo suficientemente rápido (y también crearé un punto de referencia PHP para verificar si mi los compañeros de trabajo tenían razón con "PHP es demasiado lento"). – dbemerlin

0

Si cada imagen diferente es identificable únicamente por un solo URL entonces yo simplemente uso de un CDN como Akamai. Deje que su script PHP haga el trabajo y deje que AKAMAI maneje la carga.

Dado que este tipo de negocio no suele tener problemas de presupuesto, ese sería el único lugar donde miraría.

Editar: eso funciona solo si encuentra un CDN que sirva este tipo de contenido para usted.

+0

Tengo que descartar esta solución, ya que el presupuesto disponible es exactamente de 0 euros (o para usted, los estadounidenses: exactamente $ 0). Ni siquiera pudimos lograr que la administración aprobara la instalación de un servidor de prueba o desarrollo (pero ahora nos lleva el doble de tiempo desarrollarlo porque los desarrolladores no cuestan nada porque ya están allí ...). Aún así, gracias por tu sugerencia. – dbemerlin

+0

Un servidor de imagen dedicado Y una red CND pueden funcionar bien juntos. Se llevará la carga de su sitio principal y las imágenes se entregarán muy rápido en todo el mundo. – adrianTNT

1

En el tiempo que se ha formulado esta pregunta, algunas compañías han surgido para tratar este tema exacto. No es un problema que esté aislado para usted o su empresa. Muchas compañías llegan al punto en que necesitan buscar una solución más permanente para sus necesidades de procesamiento de imágenes.

Servicios como imgix sirven como proxy y CDN para operaciones de imagen como redimensionar y aplicar superposiciones. Al manipular la URL, puede aplicar diferentes transformaciones a cada imagen. imgix sirve miles de millones de solicitudes por día.

También puede ponerse de pie servicios por su cuenta y ponerlos detrás de un CDN. Los proyectos de código abierto como imageproxy son buenos para esto. Esto pone la carga del mantenimiento en su equipo de operaciones.

(Aviso:. Yo trabajo para imgix)

1

Lo que se busca es el más igualado por Thumbor http://thumbor.readthedocs.org/en/latest/index.html, que es de código abierto, respaldado por una gran empresa (significa que no va a desaparecer mañana), y los barcos con muchas funciones agradables, como detectar lo que es importante en una imagen al recortar.

Para bajo costo más CDN, sugiero combinarlo con almacenamiento en la nube y AWS, o una solución comparable con una CDN gratuita como Cloudflare. Puede que estos no sean los mejores proveedores de CDN, pero al menos aún funcionan mejor que un servidor y también descargan su servidor de imágenes a bajo precio. Además, le ahorrará un TON de costo de ancho de banda.

0

Este mismo problema está siendo resuelto por los servicios de cambio de tamaño de imagen dedicados a esta tarea. Proporcionan siguientes características:

  1. En CDN incorporado - usted no necesita preocuparse acerca de la distribución de imágenes
  2. tamaño de imagen sobre la marcha - cualquier tamaño necesario está disponible
  3. No hay almacenamiento necesario - que acaba de imagen base de tiendas y todos las variantes son manejadas por el servicio
  4. Librerías de ecosistemas: puede incluir Javascript y su trabajo está hecho para todos los dispositivos y todos los navegadores.

Uno de estos servicios es Gumlet. También puede probar alguna alternativa de código abierto como el complemento nginx, que también puede cambiar el tamaño de la imagen sobre la marcha.

(Trabajo para Gumlet.)

Cuestiones relacionadas