web-dev-qa-db-fra.com

Produire une image dans PHP

J'ai une image $file (par exemple ../image.jpg)

qui a un type mime $type

Comment puis-je le sortir sur le navigateur?

62
steven
$file = '../image.jpg';
$type = 'image/jpeg';
header('Content-Type:'.$type);
header('Content-Length: ' . filesize($file));
readfile($file);
120
Emre Yazici

Si vous avez la liberté de configurer vous-même votre serveur Web, des outils tels que mod_xsendfile (pour Apache) sont considérablement mieux que de lire et d’imprimer le fichier en PHP. Votre code PHP ressemblerait à ceci:

header("Content-type: $type");
header("X-Sendfile: $file"); # make sure $file is the full path, not relative
exit();

mod_xsendfile récupère l'en-tête X-Sendfile et envoie le fichier au navigateur lui-même. Cela peut faire une réelle différence en termes de performances, en particulier pour les gros fichiers. La plupart des solutions proposées lisent l'intégralité du fichier en mémoire, puis l'impriment. Cela convient pour un fichier image de 20 Ko, mais si vous avez un fichier TIFF de 200 Mo, vous aurez inévitablement des problèmes.

29
Benjamin Wohlwend
$file = '../image.jpg';

if (file_exists($file))
{
    $size = getimagesize($file);

    $fp = fopen($file, 'rb');

    if ($size and $fp)
    {
        // Optional never cache
    //  header('Cache-Control: no-cache, no-store, max-age=0, must-revalidate');
    //  header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
    //  header('Pragma: no-cache');

        // Optional cache if not changed
    //  header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime($file)).' GMT');

        // Optional send not modified
    //  if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) and 
    //      filemtime($file) == strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']))
    //  {
    //      header('HTTP/1.1 304 Not Modified');
    //  }

        header('Content-Type: '.$size['mime']);
        header('Content-Length: '.filesize($file));

        fpassthru($fp);

        exit;
    }
}

http://php.net/manual/en/function.fpassthru.php

22
Mike
header('Content-type: image/jpeg');
readfile($image);
3
code_burgar

Essaye ça:

<?php
  header("Content-type: image/jpeg");
  readfile("/path/to/image.jpg");
  exit(0);
?>
3
Carlos Lima

(Étendre la réponse acceptée ...)  

J'avais besoin de: 

  1. log vues d'une jpg image et une animation gif, et, 
  2. assurez-vous que les images ne sont jamais mises en cache (chaque vue est donc enregistrée), et, 
  3. aussi conserver le extensions de fichier d'origine

J'ai accompli cela en créant un fichier "secondaire" .htaccess dans le sous-dossier où se trouvent les images.
Le fichier ne contient qu'une seule ligne: 

AddHandler application/x-httpd-lsphp .jpg .jpeg .gif

Dans le même dossier, j'ai placé les deux fichiers d'image "d'origine" (nous les appellerons orig.jpg et orig.gif), ainsi que deux variantes du script [simplifié] ci-dessous (enregistrées en tant que myimage.jpg et myimage.gif) ...

<?php 
  error_reporting(0); //hide errors (displaying one would break the image)

  //get user IP and the pseudo-image's URL
  if(isset($_SERVER['REMOTE_ADDR'])) {$ip =$_SERVER['REMOTE_ADDR'];}else{$ip= '(unknown)';}
  if(isset($_SERVER['REQUEST_URI'])) {$url=$_SERVER['REQUEST_URI'];}else{$url='(unknown)';}

  //log the visit
  require_once('connect.php');            //file with db connection info
  $conn = new mysqli($servername, $username, $password, $dbname);
  if (!$conn->connect_error) {         //if connected then save mySQL record
   $conn->query("INSERT INTO imageclicks (image, ip) VALUES ('$url', '$ip');");
     $conn->close();  //(datetime is auto-added to table with default of 'now')
  } 

  //display the image
  $imgfile='orig.jpg';                             // or 'orig.gif'
  header('Content-Type: image/jpeg');              // or 'image/gif'
  header('Content-Length: '.filesize($imgfile));
  header('Cache-Control: no-cache');
  readfile($imgfile);
?>

Les images sont rendues (ou animées) normalement et peuvent être appelées de n'importe quelle manière habituelle pour les images (comme une balise <img>) et enregistreront un enregistrement de l'adresse IP visitée, tout en étant invisible pour l'utilisateur.

0
ashleedawg

Vous pouvez utiliser finfo (PHP 5.3+) pour obtenir le bon type MIME.

$filePath = 'YOUR_FILE.XYZ';
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$contentType = finfo_file($finfo, $filePath);
finfo_close($finfo);

header('Content-Type: ' . $contentType);
readfile($filePath);

PS: vous n'avez pas à spécifier Content-Length, Apache le fera pour vous.

0
Fabien Sa

Pour le prochain gars ou fille qui rencontre ce problème, voici ce qui a fonctionné pour moi:

ob_start();
header('Content-Type: '.$mimetype);
ob_end_clean();
$fp = fopen($fullyQualifiedFilepath, 'rb');
fpassthru($fp);
exit;

Vous avez besoin de tout cela, et seulement de cela. Si votre type MIME varie, jetez un oeil à mime_content_type de PHP ($ filepath)

0
Hans
<?php $data=file_get_contents(".../image.jpg" );header("Content-type: image/png"); echo $data; ?>

La première étape consiste à récupérer l'image depuis un emplacement particulier, puis à la stocker dans une variable à cette fin, nous utilisons la fonction functio file_get_contents () avec la destination comme paramètre. Ensuite, nous définissons le type de contenu de la page de sortie en tant que type d'image à l'aide du fichier d'en-tête. Enfin, nous imprimons le fichier récupéré en utilisant echo.

0
Vishnu Pradeep
<?php

header("Content-Type: $type");
readfile($file);

C'est la version courte. Il y a quelques petites choses supplémentaires que vous pouvez faire pour rendre les choses plus agréables, mais cela fonctionnera pour vous.

0
Matthew Scharley

Vous pouvez utiliser header pour envoyer le type de contenu approprié:

header('Content-Type: ' . $type);

Et readfile pour afficher le contenu de l'image:

readfile($file);


Et peut-être que (probablement pas nécessaire, mais juste au cas où), vous devrez aussi envoyer l'en-tête Content-Length:

header('Content-Length: ' . filesize($file));


Remarque: assurez-vous de ne rien produire d'autre que vos données d'image (sans espace, par exemple), sinon l'image ne sera plus valide.

0
Pascal MARTIN