在PHP中输出一个图像

回答 12 浏览 15万 2009-12-05

我有一个图像 $file ( 例如 ../image.jpg )

mime 类型为$type

我怎样才能将其输出到浏览器?

steven 提问于2009-12-05
到目前为止,你都试过什么?使用标签有什么问题吗?Nico Haase 2020-11-17
12 个回答
#1楼 已采纳
得票数 150
$file = '../image.jpg';
$type = 'image/jpeg';
header('Content-Type:'.$type);
header('Content-Length: ' . filesize($file));
readfile($file);
Emre Yazici 提问于2009-12-05
PHP和/或服务器将为你处理内容长度问题。Matthew Scharley 2009-12-05
为方便起见,内容长度的标题。Emre Yazici 2009-12-05
由于某些原因,当我试图通过绝对路径访问图片时,filesize失败了,所以我评论了这一行,代码工作得很好。kiranvj 2013-03-30
最好不要放Content-Length,特别是如果你的网络服务器启用了GZip,因为你会告诉浏览器期望的字节数比实际到达的多,它将等待超时。这可能会产生不好的后果,例如,你有JS在等待事件。Coder 2014-05-23
确保 "Content-Type "中的Type是大写的。我刚刚遇到这种情况,它是 "Content-type",结果是一堆乱七八糟的东西。AllisonC 2017-06-21
#2楼
得票数 32

如果你有自己配置网络服务器的自由,像mod_xsendfile(用于Apache)这样的工具比在PHP中读取和打印文件要好得多。你的PHP代码会是这样的。

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

mod_xsendfile拾取X-Sendfile头并将文件发送到浏览器本身。这可以在性能上产生真正的差异,特别是对于大文件。大多数建议的解决方案都是将整个文件读入内存,然后打印出来。这对一个20k字节的图像文件来说是可以的,但如果你有一个200MB字节的TIFF文件,你肯定会遇到问题。

Benjamin Wohlwend 提问于2009-12-05
关于文件大小和潜在的内存问题的有趣评论,由于在阅读所有的文件时Ian 2011-02-08
#3楼
得票数 29
$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

Mike 提问于2012-02-28
Mike 修改于2012-02-28
@Michael via php.net getimagesize()函数将确定任何给定图像文件的大小,并返回尺寸以及文件类型和一个高度/宽度文本字符串,以便在正常的HTML IMG标签和相应的HTTP内容类型中使用。ReynekeVosz 2016-03-22
#4楼
得票数 5
header('Content-type: image/jpeg');
readfile($image);
code_burgar 提问于2009-12-05
#5楼
得票数 4

尝试一下这个。

<?php
  header("Content-type: image/jpeg");
  readfile("/path/to/image.jpg");
  exit(0);
?>
Carlos Lima 提问于2009-12-05
#6楼
得票数 3

对于下一个遇到这个问题的人或女孩,这里有对我起作用的方法。

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

你需要所有这些,而且只需要这些。如果你的mimetype不一样,看看PHP的mime_content_type($filepath)

Hans 提问于2019-01-18
为 "mime_content_type($filepath) "部分投上一票。谢谢!rockstardev 2019-04-26
#7楼
得票数 2

(扩展接受的答案...)@

我需要这样做。

  1. log 查看jpg 图像的 and 动画gif
  2. 确保图像从不缓存(因此每个视图都会被记录),并且,
  3. 保留 原文件扩展名

我是通过在图片所在的子文件夹中创建一个"二级".htaccess文件来实现的。
该文件只包含一行。

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

在同一个文件夹中,我放置了两个 "原始 "图像文件(我们称之为orig.jpgorig.gif),以及下面[简化]脚本的两个变体(保存为myimage.jpgmyimage.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);
?>

图像正常渲染(或动画),并且可以以任何图像的正常方式调用(如<img>标签),并将保存访问IP的记录,同时对用户不可见。

ashleedawg 提问于2019-02-16
#8楼
得票数 1

您可以使用标题来发送正确的Content-type。

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

readfile 来输出图片的内容:

readfile($file);


也许(可能没有必要,但是,以防万一)你也必须发送Content-Length头:

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


注意:请确保您不输出除图像数据之外的任何其他内容(例如,没有空格),否则它将不再是有效的图像。

Pascal MARTIN 提问于2009-12-05
#9楼
得票数 1
    $file = '../image.jpg';
    $type = 'image/jpeg';
    header('Content-Type:'.$type);
    header('Content-Length: ' . filesize($file));
    $img = file_get_contents($file);
    echo $img;

这对我来说是有效的!我在code igniter上进行了测试。如果我使用readfile,图片就不会显示。有时只显示jpg,有时只显示大文件。但是当我把它改成 "file_get_contents "后,我得到了这个味道,而且成功了!这是截图: 数据库中 "安全图片 "的截图

Tomo Hadi Sutomo 提问于2017-03-01
Tomo Hadi Sutomo 修改于2017-03-01
#10楼
得票数 0
<?php

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

这就是简短的版本。你可以做一些额外的小事情来使事情变得更漂亮,但这对你来说是可行的。

Matthew Scharley 提问于2009-12-05
#11楼
得票数 0

您可以使用 finfo (PHP 5.3+ ) 以获得正确的 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:你不必指定Content-Length,Apache 会为你做。

Fabien Sa 提问于2015-10-22
#12楼
得票数 0
header("Content-type: image/png"); 
echo file_get_contents(".../image.png");

第一步是从一个特定的位置检索图像,然后将其存储到一个变量中,为此我们使用函数file_get_contents(),并将目的地作为参数。 接下来我们使用头文件将输出页面的内容类型设置为图像类型。 最后我们使用echo打印检索到的文件。

Randomhex 提问于2019-04-30
Community 修改于2020-11-17
您好,欢迎来到Stack Overflow!你能不能更新一下你的答案,解释一下你的解决方案为什么会成功?你能不能把你的答案周围的引号去掉,因为那会使语法高亮器把它当作一个字符串字面。谢谢!Michael Cordingley 2019-04-30
请分享一些解释。例如,你为什么设置Content-type: image/png来输出JPG图片?另外,为什么要把整个文件读到一个变量中?readfile不是应该有更好的内存性能吗?Nico Haase 2020-11-17
标签