2012-01-21 97 views
3

我有一个类可以渲染图像的几个函数。用php渲染图像用html输出它<img>标签

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

然后我有一个包含HTML代码和我的PHP文件,我想输出的图像的< 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标记的来源吗?

+0

你应该得到无功能的垃圾,而不是一个空白屏幕。提高error_reporting或查看error.log。此外,' - > Render()'函数将输出img数据,而不是返回它。首先,而不是对象接口。 – mario

回答

3

你必须把它分解:

Render(...)会写一个临时文件(带有随机名称),可以从网络访问一段时间。

新方法Output()将返回上面提到的随机名称。

然后在输出HTML之前调用Render()并使用Output()嵌入URL。

作为替代方案,您可以使用一些文件或数据库来交换参数,本质上有一些方法Prepare(...)?写PARAMS文件或数据库,并Render()读取这些并再次放置文件等

作为另一种选择(不写入文件系统):您可以实现包括使用data: URI的图像数据,但根据使用的浏览器,图像大小将受到限制,并且无法以这种方式缓存数据(即,您必须始终发送数据)。

根据你想要达到的目标,你也可能有运气嵌入一个SVG图像。这将提供在就地使用,同时仍然使用较少带宽,可扩展等等的巨大优势。缺点是,这仅在最新的浏览器(类似于data:)中受支持,但没有大小限制。


编辑:使用的base64 /嵌入的方式得到它更棘手导致这样的一个位(未经测试,但应工作):

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 
+0

我用ob_start()来处理你的例子。从输出缓冲区中读取页面时,页面加载速度是否会变慢?或者这是解决我遇到的问题的完全合法的方法吗?从缓冲区中读取的速度是否取决于我的主页上同时有多少访问者,并使主页变慢? – Rox

+0

在这种情况下,您不应该注意到任何重大延迟。 'ob_start()'只是让PHP等待发送输出到'stdout'(直到脚本结束或使用了'ob_end _ *()'函数之一)。首先写入磁盘应该更有效。在幕后,它类似于写入流然后再次读取内容。除非形象真的很大,否则更多的参观者不应该引起任何明显的影响。但另一方面:如果这会导致这样的问题,其他解决方案也会这样做。正如我所提到的,只是不要将它用于太大的图像。 – Mario

4

您可以Base64编码的图像,并使用数据URL方案:

data:[<MIME-type>][;charset=<encoding>][;base64],<data> 

如。

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot"> 

所以,如果你包括,而不是原始图像,你可以做到你想要的。

(从Wikipediea例子)

+0

从磁盘加载PNG文件时,我知道它的工作原理,但是当我使用php函数imagecreateimagepng动态创建图像时,我没有得到它的工作,它只是打印图像,而不是html内容。看看我上面的例子。 – Rox

+0

更新了我的答案,其中包括一个应该适用于动态图像的方法。 – Mario

+0

是的。所以,你的做法是让你的img标签的src =''参数指向一个像这样的脚本,那么php脚本(render_image.php)将会运行你的渲染函数,它会输出标题和生成的图像的主体。这将不会将任何图像数据写入硬盘。 – ralfe

1

我有几乎同样的问题,前一阵子。你可以找到一个解决方案,在这里它的一些可能出现的问题:Inline generated images exceeding length

基本我想你要找的是<img src="data:image/png;base64,[data in base64]"/>

2

为空白屏幕最可能的原因有处理两组正在提交的标题数据。因此,您首先运行以下声明:

echo "<htlm><head></head><body>"; 

这将自动设置发送到浏览器的数据的内容类型。 接下来,运行此行:

echo "<img src=\"".$render->Render(1)."\" />"; 

然后使这条线来运行:

header("Content-type: image/png"); 

这则尝试设置不同的页眉到它已经被先发回声声明。

我推荐使用Render()函数来接受文件名,然后将图像写入该文件并返回指向所写入图像文件的路径。这样,您不会尝试将同一个流中的图像文件和html文件输出到浏览器。

问候, 拉尔夫

+0

是否可以创建未保存到磁盘的文件?我不想将图像保存到磁盘上,只需在浏览器上创建并呈现图像即可。 – Rox