使用 php 渲染图像并使用 html <img> 标签输出
Posted
技术标签:
【中文标题】使用 php 渲染图像并使用 html <img> 标签输出【英文标题】:Render image with php an output it with the html <img> tag 【发布时间】:2012-02-15 16:16:11 【问题描述】:我有一个类有几个可以渲染图像的函数。
// render.php
class Render
public function Render($some_arguments)
...
header("Content-Type: image/png");
$im = @imagecreate(110, 20)
or die("Cannot Initialize new GD image stream");
$background_color = imagecolorallocate($im, 0, 0, 0);
$text_color = imagecolorallocate($im, 233, 14, 91);
imagestring($im, 1, 5, 5, "A Simple Text String", $text_color);
imagepng($im);
return "data:image/png;base64,".base64_encode($im);
然后我的 php 文件包含 html 代码以及我想在 < img>
标签内输出图像的位置:
// index.php
include("render.php");
$render = new Render();
echo "<htlm><head></head><body>";
echo "<img src=\"".$render->Render(1)."\" />";
echo "</body></html>";
当我在浏览器中运行 index.php 时,我只是得到一个空白屏幕。
我不能使用函数调用作为图像源吗?我知道我可以使用 php 文件作为源,比如< img src="render_image.php" />
,但是我不能以面向对象的方式发送任何参数(我知道我可以使用 $_GET 来检索参数),但我想用不错的面向对象编写的代码。
那么,有没有什么方法可以使用函数调用作为 html 标签的来源?
【问题讨论】:
您应该得到无法正常工作的垃圾,而不是空白屏幕。提出 error_reporting 或查看 error.log。->Render()
函数也会输出 img 数据,而不是返回它。首先处理它而不是对象接口。
【参考方案1】:
您可以对图像进行 BASE64 编码并使用数据 url 方案:
data:[<MIME-type>][;charset=<encoding>][;base64],<data>
例如。
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" >
因此,如果您包含它而不是原始图像,您可以完全按照您的意愿行事。
(来自Wikipediea的示例)
【讨论】:
我在从磁盘加载 PNG 文件时可以正常工作,但是当我使用 php 函数imagecreate
和 imagepng
动态创建图像时,我没有让它工作,它只是打印图像,而不是 html 内容。看看我上面的例子。
更新了我的答案以包含一种适用于动态图像的方法。
是的。所以,你的做法是让你的 img 标签的 src='' 参数指向一个像 这样的 php 脚本,然后是那个 php 脚本(render_image.php ) 将按原样运行您的渲染函数,该函数输出生成图像的标题和正文。无需将任何图像数据写入硬盘即可。【参考方案2】:
你必须拆分它:
Render(...)
将写入一个临时文件(具有随机名称),该文件可在一段时间内通过网络访问。
一个新方法Output()
将返回上面提到的随机名称。
然后在输出 HTML 之前调用 Render()
并使用 Output()
嵌入 URL。
作为替代方案,您可以使用一些文件或数据库来交换参数,本质上是一些方法Prepare(...)
?将参数写入文件或数据库,Render()
读取这些参数并再次放置文件等。
作为另一种选择(不写入文件系统):您可以使用data:
uri 实现包含图像数据,但图像大小将根据所使用的浏览器而受到限制,并且您无法缓存数据这种方式(即你必须一直发送)。
根据您要实现的目标,您可能也很幸运能够嵌入 SVG 图像。这将提供在原地同时使用较少带宽、可扩展等的巨大优势。缺点是,这仅在最新的浏览器中受支持(类似于data:
),但没有大小限制。
编辑:使用 base64/embedded 方法会有点棘手,导致类似这样的事情(未经测试,但应该可以工作):
ob_start(); // buffers future output
imagepng($img); // writes to output/buffer
$b64 = base64_encode(ob_get_contents()); // returns output
ob_end_clean(); // clears buffered output
【讨论】:
我通过 ob_start() 将它与您的示例一起使用。从输出缓冲区读取时页面加载是否会变慢,或者这是解决我遇到的问题的完全合法的方法?从缓冲区读取的速度是否取决于我的主页上同时有多少访问者并使主页速度变慢? 在这种情况下,您应该不会注意到任何明显的延迟。ob_start()
只是导致 PHP 等待将输出发送到 stdout
(直到脚本结束或使用 ob_end_*()
函数之一)。它应该仍然比先写入磁盘更有效。在幕后,它类似于写入流然后再次读取内容。除非图像真的很大,否则更多的访问者不会造成任何明显的影响。但另一方面:如果这会导致此类问题,其他解决方案也会这样做。正如我所提到的,只是不要将它用于太大的图像。【参考方案3】:
不久前我遇到了几乎相同的问题。你可以在这里找到解决方案和一些可能的问题:Inline generated images exceeding length
我认为您正在寻找的基本是<img src="data:image/png;base64,[data in base64]"/>
【讨论】:
【参考方案4】:空白屏幕的最可能原因与提交的两组标题数据有关。所以,首先你运行这个语句:
echo "<htlm><head></head><body>";
这将自动设置发送到浏览器的数据的内容类型。 接下来,您正在运行这一行:
echo "<img src=\"".$render->Render(1)."\" />";
这会导致该行运行:
header("Content-type: image/png");
然后尝试将不同的标头设置为已由第一个 echo 语句发送的标头。
我建议更改 Render() 函数以接受文件名,然后将图像写入该文件并返回指向已写入图像文件的路径。这样,您就不会尝试将同一流中的图像文件和 html 文件输出到浏览器。
问候, 拉尔夫
【讨论】:
是否可以创建不保存到磁盘的文件?我不希望将图像保存到磁盘,只是在浏览器上直接创建和渲染。 这没有回答问题,显然未经测试,因为它包含错字。以上是关于使用 php 渲染图像并使用 html <img> 标签输出的主要内容,如果未能解决你的问题,请参考以下文章