1. 程式人生 > >利用PHP實現文字繪製到新的圖片上的功能

利用PHP實現文字繪製到新的圖片上的功能

思想和行動 總有一個不能落後於人

雖然寫出來了js實現文字和圖片載入到一起生成一個新的圖片的功能,但是我沒有用js實現一個把生成的圖片下載到本地的過程,請賭神看了看,賭神說他是用的php寫的,我想既然他用php寫了,我用js就不太方便獲得指導啊,於是乎就順便看了一下如何用php實現該功能。

百度了一下發現有現成的程式碼,所以為了方便我也就不浪費時間了,直接copy了人家的程式碼。

function generateImg($source, $text1, $text2, $text3, $font = './msyhbd.ttf') {
	$date = '' . date ( 'Ymd' ) . '/';
	$img = $date . md5 ( $source . $text1 . $text2 . $text3 ) . '.jpg';
	if (file_exists ( './' . $img )) {
		return $img;
	}

	$main = imagecreatefromjpeg ( $source );

	$width = imagesx ( $main );
	$height = imagesy ( $main );

	$target = imagecreatetruecolor ( $width, $height );

	$white = imagecolorallocate ( $target, 255, 255, 255 );
	imagefill ( $target, 0, 0, $white );

	imagecopyresampled ( $target, $main, 0, 0, 0, 0, $width, $height, $width, $height );

	$fontSize = 18;//磅值字型
	$fontColor = imagecolorallocate ( $target, 255, 0, 0 );//字的RGB顏色
	$fontBox = imagettfbbox($fontSize, 0, $font, $text1);//文字水平居中實質
	imagettftext ( $target, $fontSize, 0, ceil(($width - $fontBox[2]) / 2), 190, $fontColor, $font, $text1 );

	$fontBox = imagettfbbox($fontSize, 0, $font, $text2);
	imagettftext ( $target, $fontSize, 0, ceil(($width - $fontBox[2]) / 2), 370, $fontColor, $font, $text2 );

	$fontBox = imagettfbbox($fontSize, 0, $font, $text3);
	imagettftext ( $target, $fontSize, 0, ceil(($width - $fontBox[2]) / 2), 560, $fontColor, $font, $text3 );

	//imageantialias($target, true);//抗鋸齒,有些PHP版本有問題,謹慎使用

	imagefilledpolygon ( $target, array (10 + 0, 0 + 142, 0, 12 + 142, 20 + 0, 12 + 142), 3, $fontColor );//畫三角形
	imageline($target, 100, 200, 20, 142, $fontColor);//畫線
	imagefilledrectangle ( $target, 50, 100, 250, 150, $fontColor );//畫矩形

	//bof of 合成圖片
	$child1 = imagecreatefromjpeg ( 'http://gtms01.alicdn.com/tps/i1/T1N0pxFEhaXXXxK1nM-357-88.jpg' );
	imagecopymerge ( $target, $child1, 0, 400, 0, 0, imagesx ( $child1 ), imagesy ( $child1 ), 100 );
	//eof of 合成圖片

	@mkdir ( './' . $date );
	imagejpeg ( $target, './' . $img, 95 );

	imagedestroy ( $main );
	imagedestroy ( $target );
	imagedestroy ( $child1 );
	return $img;
}
//http://my.oschina.net/cart/
generateImg ( 'http://1.popular.sinaapp.com/munv/pic.jpg', 'my.oschina.net/cart', 'PHP文字水平居中', '3個字' );
exit ();

簡單的介紹一下這個程式碼;

$main = imagecreatefromjpeg ( $source );//imagecreatefromjpeg() 返回一影象識別符號,代表了從給定的檔名取得的影象。所以就是從source取得影象

$width = imagesx ( $main );
$height = imagesy ( $main ); //這是可以獲得取得影象的高和寬 其實 也可以自己設定一個值 這取決於你想要的最終的影象的寬高

$target = imagecreatetruecolor($width,$height); imagecreatetruecolor 新建了一個黑色的影象 可以設定寬和高

$white = imagecolorallocate($target,255,255,255);

imagefill($target,0,0,$white);這是給target這個影象背景色調為白色。

imagecopyresample($target,$main,0,0,0,0,$width,$height,$width,$heigh);//重新取樣拷貝部分影象並調整大小

$fontSize = 18; //這個fontSize是到時候用imagettfobbox的時候會用到的。已經判斷居中的時候會用到

$fontColor = imagecolorallocate($target,255,0,0);

$fontBox = imagettfbbox($fontSize,0,$font,$text1);

imagettftext($target ,$fontSize,0,ceil(($width - $fontBox[2])/2),190,$fontColor,$text1);

重點分析一下下面幾個函式imagettfbox 和imagettftext

關於imagettfbox

imagettfbox ——取得使用TrueType字型的文字範圍 簡單查了一下 TrueType字型是非常常見的字型格式,一般用的ttf和ttc就屬於TrueType字型的範疇。

imagettfbbox($size,$angle,$fontfile,$text)第一個傳入的值是size 特質畫素角度的大小,第二個傳入的值角度,順時針計算,0的時候為三點鐘中方向,第三個傳入的值是字型的檔名,可以是URL,第四個text是要傳入的字串。

imagegettfbox()返回一個含有8個單元的陣列表示了文字外框的四個角: 這些點是相對於文字 而和角度無關,因此左上角指的是以水平方向看文字時其左上角。

0  左下角X位置

1  左下角Y位置

2  右下角X位置

3  右下角Y位置

4  右上角X位置

5  右上角Y位置

6  左上角X位置

7  左上角Y位置

——————————————————————————————————————————————————————————————————————————————

測試部分待新增。。。。。。。目前他說這個

——————————————————————————————————————————————————————————————————————————————

 關於imagegettftext的使用方法,這是一個向圖片中寫入文字的方法,


一共有八個引數,缺一不可,

imagettftext($image,$size,$angle,$x,$y,$color,$fontfile,$text);

1)$image 這個是畫布資源 也就是即將要填充文字的圖片

2)$size  字型大小,其長度依賴與GD庫的版本,對於GD1來說是畫素,對於GD2來說是磅值,現在一般都是GD2了,所以運用的就是磅值。

磅值是一個長度單位,把一英寸分成72份,每一份就是1磅。磅值是一個絕對的物理單位。而畫素沒有固定大小,而是與解析度有關。高解析度的顯示器畫素就很小。

3) $angle 是旋轉角度  角度的單位是度,而不是弧度,旋轉的中心點就是引數$x,$y。

4)

5) $x ,$y被繪製字串的第一個字元的基線點,單位是畫素。這裡涉及到字型設計的基本知識--基線,這個點絕對不是左上角,而具體是什麼取決於所使用的字型是如何設計的。對於宋體、楷體、黑體等常見的字型中的漢子,這個點大概位於字型的左下部分;而對於英文字母和標點符號,則各部相同。如下圖:


6)$color 字型的顏色 

7)$fontfile 字型檔案 也就是包含TrueType字型的檔案,如楷體simkai.ttf。這種檔案格式是有標準規範的,而且與平臺無關。所以可以直接把Window系統的字型檔案拷貝到Linux下面使用。

8)$text 要渲染的字串,需要注意必需是UTF-8編碼的字串。說道字串不得不提到PHP的string資料型別。雖然名為string,其實PHP語言本身並不認識各種字元編碼,他只是簡單的把string看做是動態增長的”位元組“陣列,例如strlen()就是返回的位元組數。而我們知道除了ASCLL編碼的字元和位元組是相同的外,幾乎沒有其他字元編碼中的字元對應一個位元組,例如一個漢子的UTF-8編碼佔用3個位元組。至於怎麼解釋其中字元編碼,需要專門的庫函式如iconv_srtlen()。如果字串使用的字面量,那麼其所在的PHP原始檔就必須編碼為UTF-8儲存。

關於該函式的幾個小技巧

1)字處理軟體的複雜之處

儘管這個函式可以顯示字串,但是針對與字處理軟體(如word)來說,並不能使用。因為一旦設計到對其的問題,此函式即不能使用了。因為他不能處理字間距,當然也無法實現分散對齊的功能,再加上每一行的”避首尾“(如,不能位於行首)要求,做好字處理並不簡單。

變通的方式是,首先通過複雜的公式計算出各個字元的準確位置,然後針對每一個字元呼叫此函式。

2)如何顯示加粗字型

對於本身幾勸粗體的字型檔案來說,這不存在任何問題,只要使用粗體檔案就可以了。問題是很多字型檔案沒有針對粗體單獨設計。GD庫中也沒一個能夠加粗顯示的函式。其解決方法說出來有點可笑,就是針對每個字元繪製兩次。第二次繪製的是的$x比第一次$x多一個畫素即可。

——————————————————————————————————————————————————————————————————————————————

imagejpeg($target,'./'.$img,95);

imagejpeg()從image影象以filename為檔名建立一個JPEG影象。可以依靠這個函式把上面生成的新影象儲存起來。

引數 image 返回的資源影象  filename 檔案儲存路徑,如果未設定,或者為NULL,將會直接輸出原始影象流。如果人呂這個引數而提供quality引數,使用null。

quality

quality為可選項,範圍從0(最差質量,檔案更小)到100(最佳質量,檔案最大)。預設為IJG預設的質量大約為75.

補充一下 關於圖片合成圖片的問題

//bof of 合成圖片

$child1 = imagecreatefromjpeg ( 'http://gtms01.alicdn.com/tps/i1/T1N0pxFEhaXXXxK1nM-357-88.jpg' );

imagecopymerge ( $target, $child1, 0, 400, 0, 0, imagesx ( $child1 ), imagesy ( $child1 ), 100 );

//eof of 合成圖片

在合成圖片之前首先你得引用到”GD庫可以操作的標誌“,也就是你要能夠讀取圖片的所有資訊,這時候通過imagecreatefromjpeg就可以有給定的檔名或者url建立一個新的影象,值得注意的是後面的fromjpeg,也就是說不同的操作圖片格式,可能還要使用不同的程式碼。

簡單搜尋了一下,的確發現了不同格式下操作辦法。所以說這裡設計到一些問題,比如我要批量操作一批圖片,給他們加上水印,而這些圖片存在多種格式,那麼怎麼來處理,是通過判斷圖片格式,來選擇操作方法,還是通過將一批圖片都轉換成某一種格式?或者有一種其他方法,可以實現無論格式都可以返回的辦法。

imagecopymerge這個函式,可以實現將圖片和圖片重疊組合的辦法。拷貝並並影象的一部分

imagecopymerge($dst_im,$src_im,$dst_x,$dst_y,$src_x,$src_y,$src_w,$src_h,$pct);

將src_im影象中的座標從src_x,src_y開始,寬度為src_w,高度為src_h的一部分拷貝到dst_im影象中座標為dst_x和dst_y的位置上,兩影象將根據pct來決定合併程度,其值範圍從0到100。當pct=0時,實際上什麼也沒做,當為100時對於調色盤影象本函式和imagecopy()完全一樣,它對真彩圖像實現了alpha透明。

簡單的來說就是將SRC_im影象載入到了DST影象中了,然後在pct設定透明度,100的時候就是不透明,完全覆蓋。0的時候就是全透明,

所以PHP中通過上面這段程式碼可以實現一個在圖片中增加文字

步驟1、讀取圖片 可以使用imagecreatefrom

步驟2、設定文字,設定字型,大小,顏色(顏色要通過imagecolorallocate來設定),同時位置效果可能要使用到imagegettfbox這個方法來獲得字串的畫素值,將文字填充用到imagettftext函式。

步驟3、新增圖片首先要讀取圖片,然後使用imagecopymerge函式。

步驟四 將合成後的圖片輸出要用到imagejpeg來輸出圖片

步驟五:最後合成圖片後要將與image關聯的記憶體消除。