用PHP脚本生成一个单个的透明像素(PNG或GIF)

62

我需要创建一个PHP程序,返回一张只有一个透明圆点的图像流(PNG或GIF格式)。

您能否给我指出一个易于使用的解决方案?


2
用静态文件不是更好吗? - mbq
如果这是为了跟踪目的,您可以创建一个 PHP 脚本来进行跟踪,然后使用 readfile 读取普通的、空白的 GIF 像素图像。 - Martin Bean
马丁,是的,它正在跟踪,但我不想从文件中读取。Sjoerd的解决方案正是我所需要的,但还是谢谢! - user333306
5个回答

174

透明的1x1像素PNG图片:

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

透明的1x1像素GIF:

header('Content-Type: image/gif');
echo base64_decode('R0lGODlhAQABAJAAAP8AAAAAACH5BAUQAAAALAAAAAABAAEAAAICBAEAOw==');

我在想,为什么需要回显任何东西?在我的测试中,即使像素没有返回,PHP仍然会跟踪信标。 - jerrymouse
17
如果没有图像返回,邮件查看器可能会向用户显示某种错误标志。 - Brilliand
我们如何控制这样的图像的颜色? - donquixote

23

在 PHP 5.4 及更高版本中,可以使用hex2bin函数,其速度大约比base64_decode快两倍(在下面的空白GIF文件测试中)。输出图像的代码如下:

透明1x1的PNG:

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

透明的1x1像素的GIF图片:

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

你可以轻松地将base64编码的数据转换为十六进制:

echo bin2hex(base64_decode($data));

或者一个文件:

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

然而,根据我的基准测试,使用 @Lukas Liesis 建议的本机 PHP 转义方法是最快的,大约比 base64_decode 快12.5倍。而且它几乎可以与任何版本的 PHP 一起使用。这里是代码片段:

透明的 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");

透明的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");

使用正则表达式创建这样的字符串很容易(因为只需执行一次,所以无需快速执行):

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

或者从文件中获取:

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

2
第一个透明的1x1 PNG:缺少结束括号:)); - Stelian

6
为了回答一些人的问题:
您必须回显图像的内容。标题只显示您将图像返回给浏览器,而不是普通文本。因此,如果您只返回标题,那么它只是一个标题 - 没有数据。但是,打印出图像的数据并完成,您刚刚发送了一张图片:)
读取文件并不好,虽然可以工作,但最好像Sjoerd在主要答案中所示那样返回原始数据。这样,您可以节省时间和服务器负载,而无需处理读取操作。从磁盘读取是一项缓慢的任务。随着SSD磁盘的速度提高,从磁盘读取的速度随着时间的推移而增加,但仍然,没有I/O到磁盘更好。
我甚至没有base64解码就拥有了这个代码,但是这张图片是白色的:
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");

也许有人知道如何将任何文件转换为这样的数据字符串吗?

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);

-1

在Linux中,您可以通过在控制台中输入以下命令来进行转换:

hexdump -v -e '"\\\x" 1/1 "%X"' image.gif; echo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接