PHP gd库澄清

3
我正在查看这段代码,已经阅读了文档,但仍然不明白它应该如何工作。代码可以正常运行,但我想知道是否应该将头文件输出为png而不是jpeg。
这段代码到底在做什么?是将png图像转换为jpeg吗?
我最终想要做的是给单个目录中的所有gif、jpg、bmp和png图像打上水印。我将所有头文件输出为jpg,无论图像类型是否正确。这样做对吗?希望我表述清楚了,我有点累。
$im2 = imagecreatefrompng($image)
imagecopy() and more code here
header("Content-Type: image/jpeg");
imagejpeg($im2,'',50);
4个回答

3
您的代码大致如下所示:

您的代码的作用如下:

// Load the PNG file from disk into memory
$im2 = imagecreatefrompng($image) 

$im2现在是一个引用图像的resource。一旦被加载到内存中,它不再是png或jpeg格式;它是原始的、未压缩的数据。图像的“格式”指定了这些原始数据如何被打包和格式化;此时,它还没有任何格式。它只是存在于内存中的数据。

// Some code which works with the image in memory, adding your watermark?
imagecopy() and more code here

// Tell the browser that we're output a JPG
header("Content-Type: image/jpeg");

如果你请求一个jpg文件(比如 http://host.com/image.jpg),那么服务器会为你编写这个头信息。如果你正在通过PHP动态生成JPG文件,你必须手动输出头信息。否则,PHP会认为你正在编写HTML,并在你通过echo或只是在<?php ?>标签外部输出文本/空白时立即为你输出适当的头信息。
// compress as a jpeg, and send to browser
imagejpeg($im2,'',50);

imagejpeg函数将原始图像压缩为JPEG格式,并将其写入文件(如果指定了文件名)或标准输出流(发送给浏览器)。技术上,为了将图像输出到浏览器,第二个参数应该是null而不是''。最后一个参数50指定JPEG的质量百分比,100表示高质量,0表示低质量。


哦,好的。如果我理解正确的话,因为保存在服务器上的图像是原始格式,那么输出的图像实际上是jpg格式的。对吗? - timmay
你说“图像随后以原始格式存储在服务器上”,这意味着它存储在磁盘上。一旦调用imagecreatefrompng,所有操作都在内存中进行。原始的PNG文件被解压缩并复制到内存中。没有文件被写入磁盘,所有图像处理都在内存中完成。最后,通过将数据传递给imagejpeg来输出图像数据,该函数将数据压缩为JPEG图像并将其发送到浏览器。同样,没有写入磁盘的操作。 - user229044
明白了,谢谢。我唯一的担心是即使将png或gif图像复制到内存中并输出到浏览器,URI中的文件扩展名仍然保持为png,我想知道是否应该为每种文件类型创建一个函数,并输出与该扩展名匹配的正确标头。如果这真的很重要的话。 - timmay
如果您想使输出更加友好,可以包含一个content-disposition响应头来指定带有正确扩展名的文件名。请参阅http://php.net/manual/en/function.header.php。 - user229044
谢谢Meagar,你一直很有帮助,其他人也是。我会查看你提供的链接以获取更多信息。 - timmay
显示剩余2条评论

1

无论原始对象的格式如何,imagejpeg函数都会以JPEG格式输出图像。如果您想保留原始格式,则需要在加载文件时确定此格式,然后在生成输出时使用不同的函数 - 有imagepng、imagegif等函数。


谢谢Alxp。所以文件扩展名,即使浏览器输出图像后仍然是png,也没问题了吗? - timmay
我在想是否应该为每种文件类型创建一个函数,并输出与扩展名匹配的标头。 - timmay

1

此代码将从PNG文件加载图像到GD资源中,然后对其进行操作,最后以不同格式(JPEG)输出图像到浏览器。

当调用imagecreatefrompng时,您不仅指定了GD应使用该文件作为其当前工作副本的图像,还告诉它从PNG格式解码并将其加载到内存中的某个未知内部格式中。此时,原始读取图像的文件格式已不再重要。在输出时,必须指定所需的格式,因为它不再具有与之相关联的格式。这就是为什么要使用imagejpeg的原因。


好的,谢谢。这正是 Megar 说的。那么让我问你这个问题。如果被操作的原始图像是一个 png 图像,当浏览器将图像输出到浏览器时,扩展名仍然是 png。这有关系吗? - timmay
文件的扩展名仍然是“.png”,但你并没有输出文件。你正在输出内存中的图像副本,这与文件完全分离。浏览器不知道文件的扩展名是什么。 - Will Vousden
好的,这确实是我在这里唯一关心的问题。所以我不需要为每种类型的输出文件创建不同的函数。这实际上是个好消息。谢谢Zakalwe。 - timmay

1

imagecreatefrompng 函数从 PNG 文件中加载图像数据。此时的图像数据仅为 GD 特定的像素数据。

imagejpeg 函数将像素数据输出为 JPEG 格式。因此,在这种情况下,您的头文件应该指定为 JPEG。


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