图像输出

可以使用 image*函数创建图像,其中*是文件格式。

他们有这个共同的语法:

bool image___(resource $im [, mixed $to [ other parameters]] )

保存到文件

如果要将图像保存到文件,可以传递文件名或打开的文件流,如 $to。如果你传递流,则无需关闭它,因为 GD 会自动关闭它。

例如,要保存 PNG 文件:

imagepng($image, "/path/to/target/file.png");

$stream = fopen("phar://path/to/target.phar/file.png", "wb");
imagepng($image2, $stream);
// Don't fclose($stream)

使用 fopen 时,请确保使用 b 标志而不是 t 标志,因为该文件是二进制输出。

千万不能试图通过 fopen("php://temp", $f)fopen("php://memory", $f) 它。由于在调用之后函数关闭了流,因此你将无法进一步使用它,例如检索其内容。

输出为 HTTP 响应

如果你想直接返回这个图像作为图像的响应(例如创建动态徽章),你不需要传递任何东西(或传递 null)作为第二个参数。但是,在 HTTP 响应中,你需要指定你的内容类型:

header("Content-Type: $mimeType");

$mimeType 是你要返回的格式的 MIME 类型。例子包括 image/pngimage/gifimage/jpeg

写入变量

有两种方法可以写入变量。

使用 OB(输出缓冲)

ob_start();
imagepng($image, null, $quality); // pass null to supposedly write to stdout
$binary = ob_get_clean();

使用流包装器

你可能有许多原因不希望使用输出缓冲。例如,你可能已经拥有 OB。因此,需要一种替代方案。

使用 stream_wrapper_register 函数,可以注册新的流包装器。因此,你可以将流传递给图像输出函数,并在以后检索它。

<?php

class GlobalStream{
        private $var;

        public function stream_open(string $path){
                $this->var =& $GLOBALS[parse_url($path)["host"]];
                return true;
        }

        public function stream_write(string $data){
                $this->var .= $data;
                return strlen($data);
        }
}

stream_wrapper_register("global", GlobalStream::class);

$image = imagecreatetruecolor(100, 100);
imagefill($image, 0, 0, imagecolorallocate($image, 0, 0, 0));

$stream = fopen("global://myImage", "");
imagepng($image, $stream);
echo base64_encode($myImage);

在此示例中,GlobalStream 类将任何输入写入引用变量(即间接写入给定名称的全局变量)。稍后可以直接检索全局变量。

有一些特别需要注意的事项:

  • 一个完全实现的流包装类应该看起来像这样 ,但是根据 __call 魔术方法的测试,只有 stream_openstream_writestream_close 是从内部函数调用的。
  • fopen 调用中不需要标记,但你至少应该传递一个空字符串。这是因为 fopen 函数需要这样的参数,即使你没有在你的 stream_open 实现中使用它,仍然需要一个虚拟参数。
  • 根据测试,stream_write 被多次调用。记得使用 .=(连接分配),而不是 =(直接变量赋值)。

用法示例

<img> HTML 标记中,可以直接提供图像而不是使用外部链接:

echo '<img src="data:image/png;base64,' . base64_encode($binary) . '">';