2010-05-19 19 views

Respuesta

16

Usted puede hacer esto en los navegadores que soportan la nueva File API del W3C, utilizando la función readAsDataURL en la interfaz FileReader y la asignación de la dirección URL de datos a la src de un img (después de lo cual se puede leer la height y width de la imagen). Actualmente Firefox 3.6 es compatible con File API, y creo que Chrome y Safari ya lo hacen o están a punto de hacerlo.

Así que su lógica durante la fase de transición sería algo como esto:

  1. detectar si el navegador es compatible con la API de archivos (que es fácil: if (typeof window.FileReader === 'function')).

  2. Si lo hace, genial, lea los datos localmente e insértelos en una imagen para encontrar las dimensiones.

  3. De lo contrario, cargue el archivo en el servidor (probablemente envíe el formulario de un iframe para evitar abandonar la página) y luego pregunte qué tamaño tiene la imagen (o simplemente solicite la imagen cargada, si prefieres).

Editar he tenido la intención de abrir el ejemplo de la API de archivos por algún tiempo; aquí hay uno:

<!DOCTYPE HTML> 
<html> 
<head> 
<meta http-equiv="Content-type" content="text/html;charset=UTF-8"> 
<title>Show Image Dimensions Locally</title> 
<style type='text/css'> 
body { 
    font-family: sans-serif; 
} 
</style> 
<script type='text/javascript'> 

    function loadImage() { 
     var input, file, fr, img; 

     if (typeof window.FileReader !== 'function') { 
      write("The file API isn't supported on this browser yet."); 
      return; 
     } 

     input = document.getElementById('imgfile'); 
     if (!input) { 
      write("Um, couldn't find the imgfile element."); 
     } 
     else if (!input.files) { 
      write("This browser doesn't seem to support the `files` property of file inputs."); 
     } 
     else if (!input.files[0]) { 
      write("Please select a file before clicking 'Load'"); 
     } 
     else { 
      file = input.files[0]; 
      fr = new FileReader(); 
      fr.onload = createImage; 
      fr.readAsDataURL(file); 
     } 

     function createImage() { 
      img = document.createElement('img'); 
      img.onload = imageLoaded; 
      img.style.display = 'none'; // If you don't want it showing 
      img.src = fr.result; 
      document.body.appendChild(img); 
     } 

     function imageLoaded() { 
      write(img.width + "x" + img.height); 
      // This next bit removes the image, which is obviously optional -- perhaps you want 
      // to do something with it! 
      img.parentNode.removeChild(img); 
      img = undefined; 
     } 

     function write(msg) { 
      var p = document.createElement('p'); 
      p.innerHTML = msg; 
      document.body.appendChild(p); 
     } 
    } 

</script> 
</head> 
<body> 
<form action='#' onsubmit="return false;"> 
<input type='file' id='imgfile'> 
<input type='button' id='btnLoad' value='Load' onclick='loadImage();'> 
</form> 
</body> 
</html> 

Funciona muy bien en Firefox 3.6. Evité el uso de cualquier biblioteca allí, así que me disculpo por los manejadores de eventos de estilo de atributo (DOM0) y demás.

+0

+1, esa es la manera de hacerlo. – YOU

+0

¡Gracias por el ejemplo! – Pointy

+0

Utilicé su solución para verificar la orientación de las imágenes antes de cargarlas a través de iOS Safari (ya que iOS elimina una gran cantidad de datos exif durante la carga, orientación, por ejemplo). Descubrí que tenía las dimensiones incorrectas si la imagen tenía pantalla: ninguna (confundía el ancho y el alto en el modo vertical). Mi manera de resolverlo fue darle una posición absoluta de -10000px más o menos. De cualquier manera, gracias por tu trabajo. Me salvó de muchos dolores de cabeza extra. – stafffan

1

No, no se puede, el nombre de archivo y el contenido del archivo se envían al servidor en http encabezado cuerpo, javascript no puede manipular esos campos.

+0

¿Hay alguna otra forma de encontrar las dimensiones en el lado del cliente? –

+0

Necesita cargarlo en otro lugar, verifíquelo en el servidor y recupere ese valor con ajax – YOU

+0

No estoy seguro de que flash lo pueda hacer o no, pero el applet de Java debería poder hacerlo. o parece que html5 podría hacer eso, ver T.J. Respuesta de Crowder – YOU

1

Si utiliza una carga de flash tal como SWFUpload, puede tener toda la información que desee, así como varias cargas en cola.

Recomiendo SWFUpload y de ninguna manera estoy asociado con ellos que no sea como usuario.

También podría escribir un control Silverlight para elegir su archivo y cargarlo.

+0

+1 se ve genial! – YOU

+0

Por supuesto, esto requiere que los usuarios permitan Flash. Muchos de nosotros bloqueamos Flash por rutina, por el momento, debido a todos los anuncios basados ​​en Flash. –

+0

concedido @TJC, pero hasta que HTML5 sea omnipresente Flash/ActiveX/Silverlight/XBap es la única opción viable para este tipo de situación. –

0

HTML5 es definitivamente la solución correcta aquí. Siempre debe codificar para el futuro, no el pasado. La mejor manera de tratar con navegadores HTML4 es recurrir a la funcionalidad degradada o usar Flash (pero solo si el navegador no es compatible con la API de archivos HTML5)

Al usar el evento img.onload podrá recuperar el dimensiones del archivo. Está trabajando para una aplicación en la que estoy trabajando.

8

El ejemplo anterior está bien, pero está lejos de ser perfecto.

var reader = new FileReader(); 

reader.onload = function(e) 
{ 
    var image = new Image(); 

    image.onload = function() 
    { 
     console.log(this.width, this.height); 
    }; 

    image.src = e.target.result; 
}; 

reader.readAsDataURL(this.files[0]); 
+0

¡Genial! Pero en mi caso, JS escribe en la consola justo después del segundo clic en el botón de carga. ¿Qué pasa? –

+0

Oh, encontré una respuesta: debería ser un evento 'onchange' instalado de 'onclick' en el elemento . De todos modos, gracias Gajus –

Cuestiones relacionadas