2009-05-22 11 views
54

Estoy tratando de leer un archivo de imagen (.jpeg para ser exactos), y 'eco' de nuevo a la salida de la página, sino que tenga es mostrar una imagen ...devuelve una página en PHP como una imagen

mi index.php tiene un enlace de imagen como esta:

<img src='test.php?image=1234.jpeg' /> 

y mi script php hace básicamente esto:

1) lea 1234.jpeg 2) el contenido del archivo de eco ... 3) tengo una sensación que necesito devolver la salida con un tipo mime, pero aquí es donde me pierdo

Una vez que lo resuelva, eliminaré la entrada del nombre de archivo y la reemplazaré con una identificación de imagen.

Si no estoy seguro o si necesita más información, responda.

+1

Sólo añadir un poco de seguridad para que los ataques como '' se pueden evitar – mixdev

Respuesta

92

El Manual de PHP tiene this example:

<?php 
// open the file in a binary mode 
$name = './img/ok.png'; 
$fp = fopen($name, 'rb'); 

// send the right headers 
header("Content-Type: image/png"); 
header("Content-Length: " . filesize($name)); 

// dump the picture and stop the script 
fpassthru($fp); 
exit; 
?> 

Los puntos importantes es que se debe enviar una cabecera Content-Type. Además, debe tener cuidado de no incluir ningún espacio en blanco adicional (como nuevas líneas) en su archivo antes o después de las etiquetas <?php ... ?>.

Como se sugiere en los comentarios, se puede evitar el peligro de espacio en blanco adicional al final de la secuencia de comandos omitiendo la ?> etiqueta:

<?php 
$name = './img/ok.png'; 
$fp = fopen($name, 'rb'); 

header("Content-Type: image/png"); 
header("Content-Length: " . filesize($name)); 

fpassthru($fp); 

Todavía es necesario para evitar cuidadosamente el espacio en blanco en la parte superior de la secuencia de comandos. Una forma particularmente complicada de espacio en blanco es UTF-8 BOM. Para evitar eso, asegúrese de guardar su secuencia de comandos como "ANSI" (Bloc de notas) o "ASCII" o "UTF-8 sin firma" (Emacs) o similar.

+12

Con ese fin, algunos (incluyendo Zend, pera, o ambas cosas - me olvido) recomiendan omitiendo el cierre ?>. Es perfectamente sintácticamente válido y no garantiza problemas con los espacios en blanco finales. –

+10

Pero, pero ...es extraño no cerrar lo que está abierto :-) –

+1

¿No omites el?>. "Más fácil" no significa "mejor". –

-5

Otra opción fácil (no es mejor, solo diferente) si no está leyendo desde una base de datos es simplemente usar una función para generar todo el código para usted ... Nota: Si también quería php para leer las dimensiones de la imagen y darle al cliente para una representación más rápida, también podría hacerlo fácilmente con este método.

<?php 
    Function insertImage($fileName) { 
    echo '<img src="path/to/your/images/',$fileName,'">';  
    } 
?> 

<html> 
    <body> 
    This is my awesome website.<br> 
    <?php insertImage('1234.jpg'); ?><br> 
    Like my nice picture above? 
    </body> 
</html> 
+0

Esta "respuesta" funcionaría, pero ** no responde a la pregunta de esta página mencionada anteriormente. Las respuestas siempre deben responder a la pregunta original. ** – Edward

3

Esto debería funcionar. Puede ser más lento.

$img = imagecreatefromjpeg($filename); 
header("Content-Type: image/jpg"); 
imagejpeg($img); 
imagedestroy($img); 
15

readfile() se utiliza comúnmente para realizar esta tarea también. No puedo decir si es una solución mejor que usar fpassthru(), pero funciona bien para mí y, de acuerdo con the docs, no presentará ningún problema de memoria.

Aquí está mi ejemplo de él en acción:

if (file_exists("myDirectory/myImage.gif")) {//this can also be a png or jpg 

    //Set the content-type header as appropriate 
    $imageInfo = getimagesize($fileOut); 
    switch ($imageInfo[2]) { 
     case IMAGETYPE_JPEG: 
      header("Content-Type: image/jpeg"); 
      break; 
     case IMAGETYPE_GIF: 
      header("Content-Type: image/gif"); 
      break; 
     case IMAGETYPE_PNG: 
      header("Content-Type: image/png"); 
      break; 
     default: 
      break; 
    } 

    // Set the content-length header 
    header('Content-Length: ' . filesize($fileOut)); 

    // Write the image bytes to the client 
    readfile($fileOut); 

} 
+0

La página 'fpassthru' docs dice" Si solo desea volcar el contenido de un archivo en el búfer de salida, sin primero modificarlo o buscar un desplazamiento en particular, es posible que desee use readfile(), que le ahorra la llamada a fopen(). " entonces ['readfile'] (http://php.net/manual/en/function.readfile.php) es mejor que' fpassthru' ya que es más eficiente en este caso. – Edward

+1

El código 'header ($ _ SERVER [" SERVER_PROTOCOL "]." 404 Not Found ");' se puede usar si el archivo no existe y se requiere una notificación de esto en la respuesta. – Edward

+0

La variable '$ fileOut' debe contener el nombre del archivo: ' $ fileOut = "your_file_name.png"; ' – metatron

0

trabajé sin Content-Length. tal razón el trabajo para una imagen remota de archivos

// open the file in a binary mode 
$name = 'https://www.example.com/image_file.jpg'; 
$fp = fopen($name, 'rb'); 

// send the right headers 
header('Cache-Control: no-cache, no-store, max-age=0, must-revalidate'); 
header('Expires: January 01, 2013'); // Date in the past 
header('Pragma: no-cache'); 
header("Content-Type: image/jpg"); 
/* header("Content-Length: " . filesize($name)); */ 

// dump the picture and stop the script 
fpassthru($fp); 
exit; 
Cuestiones relacionadas