2012-01-21 99 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