2011/03/14

6 maneras de cargar imágenes

Que eres de los que siempre usa <img src="imagen"/> y no sabes que existen varias maneras de hacerlo con diversas ventajas?... pues sigue leyendo.

Siempre desde el punto de vista de reducción de peticiones y velocidad vamos a ver 6 maneras de asignar las imágenes reduciendo la penalización en la carga de la imagen por la apertura de conexiones para mostrarlas.

1.- La clásica
0 optimizaciones. Me aburroooo... pero si no, dime cómo llego a tener 6 maneras, ein?
<img src="/images/meaburro.gif"/>
2.- Carga por javascript
Esta es la más sencilla. Se crea el tag en el html y luego se asigna por código. El ejemplo que he puesto es tonto, pero este método es realmente bueno en mejorar la respuesta realizando lazy-load de las imágenes cuando haga falta de la misma manera que las peticiones Ajax agilizan el funcionamiento de la página distribuyendo las peticiones a lo largo del tiempo.
<img src="" id="imagen">
<script>
    document.getElementById("imagen").src = "/images/imagen.png";
    $("#imagen").attr("src", "/images/imagen.png"); // versión jQuery
</script>
3.- Inclusión de la imagen en el CSS
Dado que el CSS se cachea, una manera de reducir drásticamente las peticiones HTTP para la carga de imágenes es que directamente NO se hagan peticiones incluyendo el contenido de las imágenes en el CSS. Para ello hay que hacerlo en 2 pasos

1 Generación a partir de un fichero con PHP (por ejemplo);
php -r "echo base64_encode(file_get_contents('imagen.png'));"
2 Inclusión del resultado en el CSS (en el ejemplo se asigna la imagen de fondo):
#elemento: background-image: url("data:image/png;base64, ...imagen...");
4.- Inclusión de imágenes en el HTML en el propio tag <img>
Si no te gusta guarrear el CSS con cosas raras, puedes optar por guarrear el HTML con cosas raras. Solo un aviso, si tu página no se cachea, estás penalizando la transferencia!. Lo primero igual que antes es generar el base64 de la imagen, acto seguido se añade el código al tag <img>. Quizás no le veas el punto, pero sigue leyendo.
<img src="data:image/png;base64,...imagen..."/>
5.- Asignación directa al src del <img> sin cargas intermedias.
Podíras decir que el método 3 es una chorrada, pero donde realmente brilla es cuando se combina con javascript. Podemos decir que es una evolución del primer método y es realmente útil para mostrar imágenes generadas como por ejemplo las que provienen de un renderizador o un raytracer (sí, ambos existen y están hechos con javascript)
<img src="" id="imagen">
<script>
    document.getElementById("imagen").src = "data:image/png;base64,...imagen...";
</script>
Ahora llega el problema de los "peros" para los métodos 3 y 4 (y posiblemente el 5 y el 6) y como siempre vienen del mismo lado... Internet Explorer para versiones anteriores a la 8. Sin embargo, se puede resolver fácilmente haciendo un par de manipulaciones muy sencillas en el CSS. Para más información para masocas que se empeñen en seguir usando IE mirad en este enlace.

6.- Canvas
Esto ya es artillería pesada de la que me gusta a mí... aquí es donde se saca el Ferrari a la calle a pasear para lucirse. Si aún no sabes lo que es el objeto canvas, o vives debajo de una piedra o te importa un carajillo de pato el tema del desarrollo web, pues ya estás tardando en enterarte. Baste decir que es el principal caballo de batalla hoy en día sobre rendimiento de navegadores ya que la mayoría (no, Internet Explorer aún no... a duras penas puede llamársele navegador) ya está acelerado por hardware dando rendimientos parecidos a aplicaciones compiladas.

Bueno, al lío. El objetivo de esta técnica es generar una imagen en el canvas y luego asignarla al <img>. Puede servir por ejemplo para aplicar una marca de agua, aplicar transformaciones a una imagen, hacer un editor de fotos online, etc...

Como no hay nada mejor que un ejemplo, ahí va (por cierto, lo he hecho con jQuery por si veis cosas "raras" como por ejemplo $('algo') ):
<script>
// Crea dinámica un elemento canvas para realizar las manipulaciones
var canvas = document.createElement('canvas'),
    ctx = canvas.getContext("2d");


// Dimensiona el canvas
canvas.width  = <ancho>;
canvas.height = <alto>;


// Realiza las operaciones sobre el cavas para navegadores con HTML5 (sí, Internet Eplorer también puede, ver Bonus!)
//... ejemplo pintando aleatoriamente píxeles en el canvas ...
var imgData = ctx.createImageData(canvas.width, canvas.height); // crea un buffer de acceso directo a los pixels del canvas
var rand = function(min, max) { return Math.floor(Math.random()*(max-min)+min); };
for (var i = 0; i < 0.9 * Math.pow(<ancho>, 2); i++) {
    var x = rand(0, canvas.width),
        y = rand(0, canvas.height),
        index = (x + y * imgData.width) * 4;


    imgData.data[index  ] = rand(0, 255); // red
    imgData.data[index+1] = rand(0, 255); // green
    imgData.data[index+2] = rand(0, 255); // blue
    imgData.data[index+3] = rand(0, 255); // alpha también aleatoria
}
ctx.putImageData(imgData, 0, 0); // aplica los cambios realizados al buffer en el canvas
//... fin ejemplo pintado aleatorio ...


// realiza la "magia" sobre la imagen de fondo de pantalla de #elemento con la función toDataURL. Para aplicarla al src, mirad el método 2
$('#elemento').css('background-image', 'url(' + canvas.toDataURL('image/png') + ')');
</script>
El resultado va en el rango de espectacular a alucinante. Libertad total para el tratamiento de imágenes.http://3nibbles.blogspot.com/2011/03/canvas-para-todos.html

    No hay comentarios:

    Publicar un comentario