An image can be created using image*
functions, where *
is the file format.
They have this syntax in common:
bool image___(resource $im [, mixed $to [ other parameters]] )
If you want to save the image to a file, you can pass the filename, or an opened file stream, as $to
. If you pass a stream, you don't need to close it, because GD will automatically close it.
For example, to save a PNG file:
imagepng($image, "/path/to/target/file.png");
$stream = fopen("phar://path/to/target.phar/file.png", "wb");
imagepng($image2, $stream);
// Don't fclose($stream)
When using fopen
, make sure to use the b
flag rather than the t
flag, because the file is a binary output.
Do not try to pass fopen("php://temp", $f)
or fopen("php://memory", $f)
to it. Since the stream is closed by the function after the call, you will be unable to use it further, such as to retrieve its contents.
If you want to directly return this image as the response of the image (e.g. to create dynamic badges), you don't need to pass anything (or pass null
) as the second argument. However, in the HTTP response, you need to specify your content type:
header("Content-Type: $mimeType");
$mimeType
is the MIME type of the format you are returning. Examples include image/png
, image/gif
and image/jpeg
.
There are two ways to write into a variable.
ob_start();
imagepng($image, null, $quality); // pass null to supposedly write to stdout
$binary = ob_get_clean();
You may have many reasons that you don't want to use output buffering. For example, you may already have OB on. Therefore, an alternative is needed.
Using the stream_wrapper_register
function, a new stream wrapper can be registered. Hence, you can pass a stream to the image output function, and retrieve it later.
<?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);
In this example, the GlobalStream
class writes any input into the reference variable (i.e. indirectly write to the global variable of the given name). The global variable can later be retrieved directly.
There are some special things to note:
__call
magic method, only stream_open
, stream_write
and stream_close
are called from internal functions.fopen
call, but you should at least pass an empty string. This is because the fopen
function expects such parameter, and even if you don't use it in your stream_open
implementation, a dummy one is still required.stream_write
is called multiple times. Remember to use .=
(concatenation assignment), not =
(direct variable assignment).In the <img>
HTML tag, an image can be directly provided rather than using an external link:
echo '<img src="data:image/png;base64,' . base64_encode($binary) . '">';