iT邦幫忙

0

php GD合成問題。

php

我使用php gd的imagecopy merge功能做圖片合成,但他會忽略png的透空,請問該怎麼解決?

http://easycaptures.com/2313023834

<html xmlns="http://www.w3.org/1999/xhtml">

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>merge testing</title>
<style type="text/css">
<!--
body {
font-size: 12px;
}
div.pos1 {
position: absolute;
left: 4px;
top: 4px;
}
div.pos2 {
position: absolute;
left: 220px;
top: 4px;
}
-->
</style>



<?php
/**
* single merge
*/
$im = imagecreatefromjpeg('p1.jpg');
$pic = imagecreatefrompng('p2.png');

imagecopy($im, $pic, 60, 60, 0, 0, imagesx($pic), imagesy($pic));
// output picture
imagejpeg($im, 'merge1.jpg', 100);

echo '<div class="pos1"><b>single merge (perfact merge)</b><br><img src="merge1.jpg"></div>';

imagedestroy($im);
imagedestroy($pic);

/**
* multi merge
*/
$im = imagecreatetruecolor(200, 400);
$p1 = imagecreatefromjpeg('p1.jpg');
$p2 = imagecreatefrompng('p2.png');

imagecopymerge($im, $p1, 0, 0, 0, 0, imagesx($p1), imagesy($p1), 100);

// merge a picture three times
$pos = 30;
for($i = 1; $i <= 3; $i++) {
// start multi merge
$np2 = imagecreatetruecolor(50, 50);
imagecopyresampled($np2, $p2, 0, 0, 0, 0, 50, 50, 100, 100);
imagecopymerge($im, $np2, 30, $pos, 0, 0, 50, 50, 100);
$pos += 60;
imagedestroy($np2);
}

// output picture
imagejpeg($im, 'merge2.jpg', 100);
echo '<div class="pos2"><b>multi merge (transparent space issue)</b><br><img src="merge2.jpg"></div>';

imagedestroy($im);
imagedestroy($p1);
imagedestroy($p2);
?>

1 個回答

14
fillano
iT邦超人 1 級 ‧ 2009-06-15 15:07:26
最佳解答

你用imagecopy就可以了,不必用imagecopymerge啦。

其實我已經在programmer-club回了: http://www.programmer-club.com.tw/ShowSameTitleN/php/9894.html

看更多先前的回應...收起先前的回應...
chan15 iT邦新手 5 級 ‧ 2009-06-15 15:09:24 檢舉

我也在那邊回了,imagecopy一次只能兩張 XD

fillano iT邦超人 1 級 ‧ 2009-06-15 16:10:22 檢舉

不論怎樣copy,一次只能兩張阿??

我想你問題出在imagecopyresample上吧?請在之前使用imagealphablending($np2, false)。

fillano iT邦超人 1 級 ‧ 2009-06-15 16:26:09 檢舉
chan15 iT邦新手 5 級 ‧ 2009-06-15 16:26:44 檢舉

不,拿掉resampled也一樣
imagecopymerge可以一次多張
imagecopymerge($im, $np2, 30, $pos, 0, 0, 50, 50, 100);
imagecopymerge($im, $np3, 30, $pos, 0, 0, 50, 50, 100);
imagecopymerge($im, $np4, 30, $pos, 0, 0, 50, 50, 100);
imagecopymerge($im, $np5, 30, $pos, 0, 0, 50, 50, 100);

最後imagejpeg($im, filename, 100)會變成上面所有圖片的合成結果
imagecopy一次就兩張,我一直強調我要"多張"合成
不知道為什麼你一直要我用imagecopy

fillano iT邦超人 1 級 ‧ 2009-06-15 17:14:42 檢舉

奇怪,imagecopy不能這樣用嗎?誰跟你說的?

fillano iT邦超人 1 級 ‧ 2009-06-15 17:25:23 檢舉

不論imagecopyXXXX,結果只會在$dst上呈現。resampled會重新取樣,可以用來改大小;merge可以調整$src合成到$dst上時的透明度。不論怎麼copy,$src是不會被影響的。多次copy也不會有問題阿???

你用其他影像處理的程式,例如win32裡面的GDI相關的image copy函數啦,SDL裡面的image copy函數啦,用法都差不多。

fillano iT邦超人 1 級 ‧ 2009-06-15 17:30:46 檢舉

http://www.fillano.idv.tw/test481.html

我改成多張合成,底下還有原始碼。如果你還不滿意,我另外作多個前景圖來合成。

fillano iT邦超人 1 級 ‧ 2009-06-15 17:47:16 檢舉

同上,我用兩個前景圖來合成。

chan15 iT邦新手 5 級 ‧ 2009-06-15 19:36:06 檢舉

咦,怪了,我之前用imagecopy合成多張會出現錯誤,十分感謝你。

chan15 iT邦新手 5 級 ‧ 2009-06-15 19:54:45 檢舉

可以順道問一下您知道如何加上字嗎?

fillano iT邦超人 1 級 ‧ 2009-06-15 20:37:44 檢舉

true type字型的方法比較簡單:

  1. copy 需要的字型到伺服器(注意版權問題,可以用linux內建的true type字型)
  2. http://tw.php.net/manual/en/function.imagettftext.php
fillano iT邦超人 1 級 ‧ 2009-06-15 20:46:33 檢舉
chan15 iT邦新手 5 級 ‧ 2009-06-16 12:22:52 檢舉

看來您真是php高手,字型路徑沒辦法用抓的是嗎?
中文也可以用所謂的true type字型嗎?如果可以的話true type字型檔案名稱為何?

fillano iT邦超人 1 級 ‧ 2009-06-16 22:42:16 檢舉

可以阿,用檔案名稱就可以啦。windows的話你可以到\windows\fonts找一找,副檔名是ttf的就可以,中文字型通常會超過10MB,很好找。

chan15 iT邦新手 5 級 ‧ 2009-06-17 16:58:18 檢舉

你是說直接這樣就可以?
$im = imagecreatetruecolor(200, 200);
$black = imagecolorallocate($im, 0, 0, 0);
// $font = '/usr/share/fonts/chinese/TrueType/uming.ttf';
$font = 'uming.ttf';
imagettftext($im, 20, 0, 0, 20, $black, $font, 'test');
imagejpeg($im, 'uploads/font.jpg', 100);
echo '<img src="uploads/font.jpg">';
imagedestroy($im);

fillano iT邦超人 1 級 ‧ 2009-06-17 18:02:23 檢舉

這樣是相對路徑吧?看你的需求,用相對路徑或絕對路徑都可以,關鍵是要找得到字型擋案。

我要發表回答

立即登入回答