note 117021 added to ref.image
| From: | ('o','x','nitrogen') | Date: | Fri, 03 Apr 2015 00:31:33 +0000 |
| Subject: | note 117021 added to ref.image | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-202152@lists.php.net to get a copy of this message | ||
I was after a technique to produce an image by using the image resources available to PHP and to
have access to the image's binary data directly in PHP WITHOUT saving to a temporary file.
My purpose of this was to produce a directory of images with small image thumbnails (16x16) next to
the filenames. Instead of having countless tiny images saved, I wanted to print out the image data
into the <img> HTML tag (inline) using the data URI scheme.
I found no such code or suggestion for this, and I've done some digging around at likely
approaches and finally came up with a solution. There may or may not be a better way of doing this,
but this way works for me.
The guts of the approach started here with the example of registering a class as a stream wrapper:
http://php.net/manual/en/stream.streamwrapper.example-1.php
- this way we have access to, and can over-ride, the behaviour of "file" I/O with a custom
wrapper.
<?php
// first, we define our class for the stream wrapper
class VariableStream {
var $position;
var $varname;
function stream_open($path, $mode, $options, &$opened_path) {
$url = parse_url($path);
$this->varname = $url['host'];
$this->position = 0;
return TRUE;
}
function stream_write($data) {
$left = substr(@$GLOBALS[$this->varname], 0, $this->position);
$right = substr(@$GLOBALS[$this->varname], $this->position+strlen($data));
$GLOBALS[$this->varname] = $left.$data.$right;
$this->position+= strlen($data);
return strlen($data);
}
function stream_eof() {
return $this->position>=strlen($GLOBALS[$this->varname]);
}
}
// register the class as a stream wrapper ("var://asdf")
stream_wrapper_register('var', 'VariableStream');
// create a really simple dynamically-generated image
// in my case, I used imagecreatefromjpeg to create 16x16 thumbnails
$im = imagecreatetruecolor(130, 36);
imagefill($im, 0, 0, 0xAAAAAA);
imagestring($im, 5, 10, 10, 'Hello world!', 0x0000FF);
// and output it to our wrapper!
imagepng($im, 'var://asdf/'); // $asdf now contains our image binary!
imagedestroy($im); // free memory
$asdf = base64_encode($asdf); // base64 encode our data for...
printf("<img alt=\"\" src=\"data:image/png;base64,%s\"/>",
$asdf);
?>
The class 'VariableStream' lacks ability to seek, ftell, and read for the sake of simple
code for my purpose. More complete code for I/O operations can be found in the example document I
references above. You could also then use fopen using the wrapper and variable name to access it
like a file again.
This technique can be applied to other functions that don't allow direct access to the data
generated to files or sockets.
Hope this helps!
----
Server IP: 72.52.91.14
Probable Submitter: 82.25.3.36
----
Manual Page -- http://php.net/manual/en/ref.image.php
Edit -- https://master.php.net/note/edit/117021
Del: integrated -- https://master.php.net/note/delete/117021/integrated
Del: useless -- https://master.php.net/note/delete/117021/useless
Del: bad code -- https://master.php.net/note/delete/117021/bad+code
Del: spam -- https://master.php.net/note/delete/117021/spam
Del: non-english -- https://master.php.net/note/delete/117021/non-english
Del: in docs -- https://master.php.net/note/delete/117021/in+docs
Del: other reasons-- https://master.php.net/note/delete/117021
Reject -- https://master.php.net/note/reject/117021
Search -- https://master.php.net/manage/user-notes.php