web-dev-qa-db-fra.com

Renvoie une page PHP comme image

J'essaie de lire un fichier image (.jpeg pour être exact) et de le renvoyer à la sortie de la page, mais j'affiche une image ...

mon index.php a un lien d'image comme celui-ci:

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

et mon script php fait essentiellement ceci:

1) lire 1234.jpeg 2) le contenu du fichier d'écho ... 3) J'ai le sentiment que je dois retourner la sortie avec un type MIME, mais c'est là que je me perds

Une fois que j'ai compris cela, je supprimerai tous les noms de fichiers et les remplacerai par un identifiant d'image.

Si je ne suis pas clair ou si vous avez besoin de plus d'informations, veuillez répondre.

60
MichaelICE

Le manuel PHP a cet exemple :

<?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;
?>

L'important est que vous devez envoyer un en-tête Content-Type. De plus, vous devez faire attention à ne pas inclure d'espace blanc supplémentaire (comme les sauts de ligne) dans votre fichier avant ou après le <?php ... ?> Mots clés.

Comme suggéré dans les commentaires, vous pouvez éviter le danger d'espace blanc supplémentaire à la fin de votre script en omettant le ?> tag:

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

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

fpassthru($fp);

Vous devez toujours éviter soigneusement les espaces blancs en haut du script. Une forme particulièrement délicate d'espace blanc est un TF-8 BOM . Pour éviter cela, assurez-vous d'enregistrer votre script sous "ANSI" (Bloc-notes) ou "ASCII" ou "UTF-8 sans signature" (Emacs) ou similaire.

105
Martin Geisler

readfile() est également couramment utilisé pour effectuer cette tâche et semble être une meilleure solution que d'utiliser fpassthru().

Cela fonctionne bien pour moi et, selon la documentation , il ne présentera aucun problème de mémoire.

Voici mon exemple en action:

$file_out = "myDirectory/myImage.gif"; // The image to return

if (file_exists($file_out)) {

    //Set the content-type header as appropriate
    $image_info = getimagesize($file_out);
    switch ($image_info[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:
            header($_SERVER["SERVER_PROTOCOL"] . " 500 Internal Server Error");
            break;
    }

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

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

}
else { // Image file not found

    header($_SERVER["SERVER_PROTOCOL"] . " 404 Not Found");

}
20

Cela devrait fonctionner. Cela peut être plus lent.

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

J'ai travaillé sans Content-Length. peut-être la raison du travail pour les fichiers image distants

// 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;
2
Berk