PHP script to render a single transparent pixel (PNG or GIF)
Asked Answered
P

5

64

I have to create a PHP that will return an image stream of one transparent dot (PNG or GIF)

Could you point me to an easy to use solution?

Patinous answered 8/7, 2010 at 12:9 Comment(3)
Isn't it better to make a static file with this?Rebozo
If this is for tracking purposes, you could create your PHP script that does the tracking but then use readfile to read a normal, blank GIF pixel image.Golter
Martin, yes it's tracking, but I don't want to read from a file. Sjoerd's solution is exactly what I needed, but thanks anyway !Patinous
S
179

Transparent 1x1 PNG:

header('Content-Type: image/png');
echo base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=');

Transparent 1x1 GIF:

header('Content-Type: image/gif');
echo base64_decode('R0lGODlhAQABAJAAAP8AAAAAACH5BAUQAAAALAAAAAABAAEAAAICBAEAOw==');
Streeter answered 8/7, 2010 at 12:13 Comment(3)
I was wondering, why is it required to echo anything at all? In my tests, even if the pixel is not returned, php still tracks the beacon.Substance
@Substance If no image is returned, the email viewer might display some sort of error symbol to the user.Discordance
How might we control the color of such image?Untouchability
F
23

In PHP 5.4 and higher it is possible to use hex2bin, which is roughly two times faster than base64_decode (tested with the blank GIF file below). The code to output images would be:

Transparent 1x1 PNG:

header('Content-Type: image/png');
die(hex2bin('89504e470d0a1a0a0000000d494844520000000100000001010300000025db56ca00000003504c5445000000a77a3dda0000000174524e530040e6d8660000000a4944415408d76360000000020001e221bc330000000049454e44ae426082'));

Transparent 1x1 GIF:

header('Content-Type: image/gif');
die(hex2bin('47494638396101000100900000ff000000000021f90405100000002c00000000010001000002020401003b'));

You can easily convert base64 encoded data into hexadecimal:

echo bin2hex(base64_decode($data));

Or a file:

echo bin2hex(base64_decode(file_get_contents($filename)));

However, using the native PHP escape method suggested by @Lukas Liesis is the fastest, about 12.5 times faster than base64_decode, according to my benchmark. And it would work with virtually any version of PHP. Here are the code snippets:

Transparent 1x1 PNG:

header('Content-Type: image/png');
die("\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\x00\x00\x01\x00\x00\x00\x01\x01\x03\x00\x00\x00\x25\xdb\x56\xca\x00\x00\x00\x03\x50\x4c\x54\x45\x00\x00\x00\xa7\x7a\x3d\xda\x00\x00\x00\x01\x74\x52\x4e\x53\x00\x40\xe6\xd8\x66\x00\x00\x00\x0a\x49\x44\x41\x54\x08\xd7\x63\x60\x00\x00\x00\x02\x00\x01\xe2\x21\xbc\x33\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82");

Transparent 1x1 GIF:

header('Content-Type: image/gif');
die("\x47\x49\x46\x38\x39\x61\x01\x00\x01\x00\x90\x00\x00\xff\x00\x00\x00\x00\x00\x21\xf9\x04\x05\x10\x00\x00\x00\x2c\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02\x04\x01\x00\x3b");

Creating such a string is easy with regular expressions (as it's done once, it doesn't have to work fast):

echo preg_replace('/../','\\x\0',bin2hex($data));

Or from a file:

echo preg_replace('/../','\\x\0',bin2hex(file_get_contents($filename)));
Ferrous answered 5/6, 2015 at 10:54 Comment(1)
the first Transparent 1x1 PNG: have a missing ending bracket: ));Straw
G
6

To answer some people's questions:

You must echo the contents of an image. The Header only shows that are you are returning an image to the browser, instead of normal text. So if you only return a header, it's just a header - no data. However, print out data of an image and done, you just sent an image :)

Reading a file is not good, it could work, but it's better to return raw data like shown in main answer by Sjoerd. This way, you save time and server load not having to process a read operation. Reading from disk is a slow task. Over time, reading from disk has increased in speed with SSD disks, but still, No I/O to disk is better.

I had this code even without base64 decode, but this image has white color:

header('Content-Type: image/gif');
// 1x1px white gif
die("\x47\x49\x46\x38\x37\x61\x1\x0\x1\x0\x80\x0\x0\xfc\x6a\x6c\x0\x0\x0\x2a\x0\x0\x0\x0\x1\x0\x1\x0\x0\x2\x2\x44\x1\x0\x3b");

Maybe someone knows how to convert any file to such data string?

Gaius answered 24/10, 2014 at 20:55 Comment(0)
S
2
header('Content-Type: image/gif');
printf('%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%', 71, 73, 70, 56, 57, 97, 1, 0, 1, 0, 128, 255, 0, 192, 192, 192, 0, 0, 0, 33, 249, 4, 1, 0, 0, 0, 0, 44, 0, 0, 0, 0, 1, 0, 1, 0, 0, 2, 2, 68, 1, 0, 59);
Sneaker answered 11/6, 2020 at 4:48 Comment(0)
N
-1

In Linux you can convert it by typing in console:

hexdump -v -e '"\\\x" 1/1 "%X"' image.gif; echo
Negation answered 18/2, 2016 at 19:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.