[l-desarrollo] Imágenes dinámicas en HTML

68 views
Skip to first unread message

Alberto Mijares

unread,
Nov 26, 2012, 4:05:56 AM11/26/12
to Aplicaciones y Desarrollo en Linux
Hola lista,

Tengo una duda con respecto a la generación de HTML con imágenes:

Cuando hay imágenes en el HTML se hace referencia a la ruta hacia un
archivo en el servidor web. Hasta ahí estamos bien. Ahora, cuando se
están generando esas imágenes al vuelo (o extrayéndolas de una base de
datos, por ejemplo), ¿es necesario crear un archivo temporal para que
pueda existir esa referencia (la ruta al archivo) en el HTML o se
puede enviar el stream directamente?

Lo que quiero evitar es, precisamente, tener que crear y eliminar esas
imágenes porque generan más cargar en el servidor y hacen más lento
todo. Como alternativa, tengo la opción de montar un RAMFS y despachar
los archivos desde ahí, pero existe el riego de agotar la RAM si las
consultas crecen en tamaño, frecuencia y concurrencia.

Luego yo haré las pruebas del cómo pero primero necesito saber si es
posible para no ponerme a probar algo que tal vez no tiene sentido. Y
si pueden darme alguna referencia, mucho mejor.

Gracias...

Saludos


Alberto Mijares
_______________________________________________
l-desarrollo mailing list
l-desa...@velug.org.ve
http://listas.velug.org.ve/mailman/listinfo/l-desarrollo

Pascual Daniel De Ruvo

unread,
Nov 26, 2012, 4:32:38 AM11/26/12
to Aplicaciones y Desarrollo en Linux
Hola Alberto,

Puedes servir las imágenes directamente sin guardarlas en un archivo temporal sin ningún problema, lo importante es que envíes el encabezado HTTP que indique el contenido correcto, algo como "Content-Type: image/jpeg" y "Content-Length: <tamaño de la imagen>".

Si buscas en google "http header jpg" el primer hit es un ejemplo, no pongo el link aquí por el lenguaje en el que está implementado :) 

Como todo en esta vida esto tiene sus ventajas y desventajas. Hacerlo de esta manera tiene sentido cuando una imagen debe ser generada solo una vez. En el caso en el que generar la imagen sea costoso en términos de procesamiento, y la misma imagen debe ser generada múltiples veces, tiene sentido guardarla ("cachearla") a un archivo.

Saludos,

PDR



2012/11/26 Alberto Mijares <amij...@gmail.com>

Angel Leon

unread,
Nov 26, 2012, 8:43:22 AM11/26/12
to Aplicaciones y Desarrollo en Linux

"¿es necesario crear un archivo temporal para que
pueda existir esa referencia (la ruta al archivo) en el HTML o se
puede enviar el stream directamente?"

En el caso de que generas la imagen en el cliente (con un CANVAS), si quieres por ejemplo subir la imagen, o hacer algo con ella, puedes pedirle al canvas que te genere una URL

canvas.toDataURL("image/jpeg");

Esto es util por ejemplo si estas haciendo un Uploader de imagenes y quieres que el usuario vea un preview de la imagen que acaba de arrastrar antes de hacer el upload, y si le quieres hacer algun tipo de procesamiento en el cliente antes de subir la imagen, utilizarias esa URL para obtener el archivo que vas a subir.

Definitivamente tienes formas de hacer que el servidor descanse con las nuevas apis de javascript, mind you, no todo esto funcionará en internet exploder.

http://twitter.com/gubatron



2012/11/26 Pascual Daniel De Ruvo <der...@gmail.com>

Camilo Torres

unread,
Nov 26, 2012, 9:25:59 AM11/26/12
to l-desa...@velug.org.ve
On Lun 26 Nov 2012 04:35:56 Alberto Mijares escribió:
> Cuando hay imágenes en el HTML se hace referencia a la ruta hacia un
> archivo en el servidor web. Hasta ahí estamos bien. Ahora, cuando se
> están generando esas imágenes al vuelo (o extrayéndolas de una base de
> datos, por ejemplo), ¿es necesario crear un archivo temporal para que
> pueda existir esa referencia (la ruta al archivo) en el HTML o se
> puede enviar el stream directamente?
>
> Lo que quiero evitar es, precisamente, tener que crear y eliminar esas
> imágenes porque generan más cargar en el servidor y hacen más lento
> todo. Como alternativa, tengo la opción de montar un RAMFS y despachar
> los archivos desde ahí, pero existe el riego de agotar la RAM si las
> consultas crecen en tamaño, frecuencia y concurrencia.
Hola:

1. Si puedes hacerlo.

2. El URL de la imagen, como se va a generar dinámicamente, en realidad sería
un URL a un programa que tome la imagen y la retorne directamente en un
Stream, por ejemplo:

http://localhost:8000/django/generar_img/gallito.jpg

Entonces el URL de *generar_img* enruta a un programa, vista o controlador que
lo que hace es buscar en la BD la imagen por su nombre *gallito.jpg* y en vez
de retornar un texto con html como haces generalmente, retornas los datos
binarios. Debes colocar el encabezado HTTP correcto para que te funcione
(Content-Type y Content-Lenght) tal como te dijeron en otro correo.

Suerte.
--
Ing. Camilo Torres

Carlos Ramírez

unread,
Nov 26, 2012, 9:34:27 AM11/26/12
to Aplicaciones y Desarrollo en Linux
Cuando hay imágenes en el HTML se hace referencia a la ruta hacia un
archivo en el servidor web. Hasta ahí estamos bien. Ahora, cuando se
están generando esas imágenes al vuelo (o extrayéndolas de una base de
datos, por ejemplo), ¿es necesario crear un archivo temporal para que
pueda existir esa referencia (la ruta al archivo) en el HTML o se
puede enviar el stream directamente?

Lo que quiero evitar es, precisamente, tener que crear y eliminar esas
imágenes porque generan más cargar en el servidor y hacen más lento
todo. Como alternativa, tengo la opción de montar un RAMFS y despachar
los archivos desde ahí, pero existe el riego de agotar la RAM si las
consultas crecen en tamaño, frecuencia y concurrencia.

 
Buenos días Alberto, no es necesario guardarlas (a no ser que como dijo Pascual, pienses servir la misma imagen muchas veces, en ese caso, para ahorrar procesamiento puedes servirla directamente). Básicamente lo que tienes es que  enviar el encabezado correcto (content-type:y content-lenght)  seguido del contenido almacenado en la base de datos. Este es un ejemplo que encontré en Google de perl y mysql[1] 


Francisco Obispo

unread,
Nov 26, 2012, 9:51:57 PM11/26/12
to Aplicaciones y Desarrollo en Linux
Las imágenes son dinámicas? es decir, las estas generando en el momento?

Por la descripción que veo, solo las estás almacenando en la BD, por lo
que vas a generar un trabajo innecesario, tanto a la base de datos, como
al programador :-S

En todo caso, puedes generar el content-type específico para el tipo de archivo
que estás generando y el browser sabrá interpretar el contenido, recuerda
tratar el contenido como binario.

<img src='/path/to/program'> y listo.

Una forma que también es estándar y muchas veces no utilizada es usar data://.

Puedes colocar el contenido completo de la imagen en un tag:

<IMG
SRC="data:image/gif;base64,R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAw
AAAC8IyPqcvt3wCcDkiLc7C0qwyGHhSWpjQu5yqmCYsapyuvUUlvONmOZtfzgFz
ByTB10QgxOR0TqBQejhRNzOfkVJ+5YiUqrXF5Y5lKh/DeuNcP5yLWGsEbtLiOSp
a/TPg7JpJHxyendzWTBfX0cxOnKPjgBzi4diinWGdkF8kjdfnycQZXZeYGejmJl
ZeGl9i2icVqaNVailT6F5iJ90m6mvuTS4OK05M0vDk0Q4XUtwvKOzrcd3iq9uis
F81M1OIcR7lEewwcLp7tuNNkM3uNna3F2JQFo97Vriy/Xl4/f1cf5VWzXyym7PH
hhx4dbgYKAAA7"
ALT="Larry">

http://www.ietf.org/rfc/rfc2397.txt

Creo que la mayoría de los browsers lo soportan, recientemente supe que estaban
usando esta técnica para generar ataques de phishing con URL shorteners,
pues data:// es un URL completo, y si colocas en el payload un archivo .gz
que tiene el HTML con las imágenes incrustadas de la misma forma, tienes
una página completa codificada en un URL ;-)

Saludos

Alberto Mijares

unread,
Nov 27, 2012, 8:41:17 AM11/27/12
to Aplicaciones y Desarrollo en Linux
Sres, muchas gracias a todos por sus respuestas.

Para mi lo más importante era estar seguro de que se pudiera hacer lo
que tenía en mente. Mi conclusión es la siguiente:

Si la respuesta del webserver será un archivo (por ejemplo un PDF o
una imagen JPG), la solución es seguir las intrucciones de mi amigo
Pascual; es decir, cambiar el header content-type de la respuesta por
el que corresponda y así el browser sabrá qué hacer con esa data. Ya
esto lo había hecho en una oportunidad.

En este caso lo que quería era construir el HTML donde se van a
mostrar ciertas imágenes. Solo que esas imágenes no están en el
filesystem en formato JPG, sino que están almacenadas en una DB Pg.
Por eso no es trivial hacer las referencias tipo
<img src="imagen.jpg"> (ya que imagen.jpg no existe), sino que de
alguna forma se debían general al vuelo.

Lo que aprendí es que el HTML *DEBE* tener una referencia a un path;
que este path debería terminar en .jpg, .png, etc, (según sea el
formato de la imagen) para que no se tenga que hacer magia negra y el
browser lo interprete sin problemas; y que existe un formato para ese
path que te permite enviar el contenido del archivo embedido en el
HTML (codificado con base64, por ejemplo), como nos ilustra Francisco
Obispo. No probé esa opción pero me pareció interesante saberlo.

Al final la respuesta que necesitaba se parece mucho a la que brindó
con claridad Camilo Torres, y gracias a que estoy trabajando con
Mojolicious fue muy fácil hacerlo. Fue algo parecido a esto:


use Mojolicious::Lite;

post '/resultado' => sub {
$self = shift;
$filtro = $self->param('filtro');
$ref = get_ref_from_db($flitro);
$self->stash($filtro);
$self->render(template => 'resultado');
};

get '/thumbnail/:ref/(:num).jpg' => sub {
$self = shift;
$ref = $self->param('ref');
$num = $self->param('num');
$pic = get_pic_from_db($ref,$num);
$self->render($data, format => 'jpg');
};

Y en el HTML del template resultado.html.ep, donde debe ir cada imagen
es algo como

<img src="<%= $self->url_for("/thumbnail/$filtro/num.jpg") %>">

Eso es todo ;-)

Nuevamente gracias y saludos

Reply all
Reply to author
Forward
0 new messages