phpで複数画像合成の方法を教えてください。


大きめの画像「base.png」に小さい画像「1.png」を合成するまでは成功したのですが、
「base.png」に連続して他の小さい画像「2.png」...「7.png」を合成したいと考えております。
2枚目以降の記述方法を教えてください。よろしくお願いいたします。

2枚合成のサンプルは下記です。

<?php
define("TEST_FILE1", "./test/base.png");
define("TEST_FILE2", "./test/1.png");

$src = imagecreatefrompng(TEST_FILE1) or die("error!\n");
$mrg = imagecreatefrompng(TEST_FILE2) or die("error!\n");

list($src_width, $src_height) = getimagesize(TEST_FILE1);
list($mrg_width, $mrg_height) = getimagesize(TEST_FILE2);

// イメージをマージ
imagecopymerge($src, $mrg, 0, 0,
0, 0, $mrg_width, $mrg_height, 100) or die("error!\n");

mb_http_output("pass");
header("Content-Type: image/png");
imagepng($src);

imagedestroy($src);
imagedestroy($mrg);
?>

回答の条件
  • 1人2回まで
  • 登録:2007/04/05 16:28:52
  • 終了:2007/04/06 08:34:44

回答(1件)

id:wizemperor No.1

wizemperor回答回数379ベストアンサー獲得回数522007/04/05 23:55:34

ポイント80pt

冗長になりますが、そのまま書くのであれば、

<?php
define("TEST_FILE1", "./test/base.png");
define("TEST_FILE2", "./test/1.png");
define("TEST_FILE3", "./test/2.png");
define("TEST_FILE4", "./test/3.png");
define("TEST_FILE5", "./test/4.png");
define("TEST_FILE6", "./test/5.png");
define("TEST_FILE7", "./test/6.png");
define("TEST_FILE8", "./test/7.png");

$src = imagecreatefrompng(TEST_FILE1) or die("error!\n");
$mrg1 = imagecreatefrompng(TEST_FILE2) or die("error!\n");
$mrg2 = imagecreatefrompng(TEST_FILE3) or die("error!\n");
$mrg3 = imagecreatefrompng(TEST_FILE4) or die("error!\n");
$mrg4 = imagecreatefrompng(TEST_FILE5) or die("error!\n");
$mrg5 = imagecreatefrompng(TEST_FILE6) or die("error!\n");
$mrg6 = imagecreatefrompng(TEST_FILE7) or die("error!\n");
$mrg7 = imagecreatefrompng(TEST_FILE8) or die("error!\n");

list($src_width, $src_height) = getimagesize(TEST_FILE1);
list($mrg1_width, $mrg1_height) = getimagesize(TEST_FILE2);
list($mrg2_width, $mrg2_height) = getimagesize(TEST_FILE3);
list($mrg3_width, $mrg3_height) = getimagesize(TEST_FILE4);
list($mrg4_width, $mrg4_height) = getimagesize(TEST_FILE5);
list($mrg5_width, $mrg5_height) = getimagesize(TEST_FILE6);
list($mrg6_width, $mrg6_height) = getimagesize(TEST_FILE7);
list($mrg7_width, $mrg7_height) = getimagesize(TEST_FILE8);

// イメージをマージ
imagecopymerge($src, $mrg1, 0, 0,
0, 0, $mrg1_width, $mrg1_height, 100) or die("error!\n");

imagecopymerge($src, $mrg2, 0, 0,
0, 0, $mrg2_width, $mrg2_height, 100) or die("error!\n");

imagecopymerge($src, $mrg3, 0, 0,
0, 0, $mrg3_width, $mrg3_height, 100) or die("error!\n");

imagecopymerge($src, $mrg4, 0, 0,
0, 0, $mrg4_width, $mrg4_height, 100) or die("error!\n");

imagecopymerge($src, $mrg5, 0, 0,
0, 0, $mrg5_width, $mrg5_height, 100) or die("error!\n");

imagecopymerge($src, $mrg6, 0, 0,
0, 0, $mrg6_width, $mrg6_height, 100) or die("error!\n");

imagecopymerge($src, $mrg7, 0, 0,
0, 0, $mrg7_width, $mrg7_height, 100) or die("error!\n");

mb_http_output("pass");
header("Content-Type: image/png");
imagepng($src);

imagedestroy($src);
imagedestroy($mrg1);
imagedestroy($mrg2);
imagedestroy($mrg3);
imagedestroy($mrg4);
imagedestroy($mrg5);
imagedestroy($mrg6);
imagedestroy($mrg7);
?>

みたいになるかと思います。

冗長なので、配列やループを使うなりして最適化したほうがいいとは思います。

id:t_yasu

できました!有り難うありがとうございます。

サーバーの負担が大きいためだと思うのですが、

大きな画像では出来ない場合もありました。

メモリ不足なのでしょうね。

配列やループなどはよく分かりませんが調べてみます。

有り難うございました。

2007/04/06 08:31:50
  • id:tobeoscontinue
    >大きな画像では出来ない場合もありました。
    >メモリ不足なのでしょうね。
    imagecopymerge()した後は$mrgは必要ないので

    imagecopymerge($src, $mrg1, 0, 0,
    0, 0, $mrg1_width, $mrg1_height, 100) or die("error!\n");
    imagedestroy($mrg1);

    のようにすることで解決できると思います。

    配列にすることで考えてみました。
    function imagecreatefrom_file($file)
    {
    $mrg = NULL;
    $info = getimagesize($file);
    if ($info) {
    if ($info[2] == IMAGETYPE_GIF)
    $mrg = imagecreatefromgif($file);
    else if ($info[2] == IMAGETYPE_JPEG)
    $mrg = imagecreatefromjpeg($file);
    else if ($info[2] == IMAGETYPE_PNG)
    $mrg = imagecreatefrompng($file);
    }
    return $mrg;
    }
    imagecreatefrompng()と同じ機能ですがgif,jpe,pngを判別して返します。

    function imagecopymerge_array($src, $datas)
    {
    foreach ($datas as $data) {
    list($x, $y, $file) = $data;
    $mrg = imagecreatefrom_file($file);
    if ($mrg) {
    $mrg_width = imagesx($mrg);
    $mrg_height = imagesy($mrg);
    // イメージをマージ
    imagecopymerge($src, $mrg, $x, $y,
    0, 0, $mrg_width, $mrg_height, 100);
    imagedestroy($mrg);
    } } }
    これは$srcで指定するイメージへ$datasで指定する画像ファイルをマージしていきます。getimagesize()はファイルの形式によっては幅と高さを決定することができず0を返す場合がありますのでimagesx,imagesyを使っています。

    使い方としては
    $src = imagecreatefrom_file(TEST_FILE1);
    // イメージをマージ
    imagecopymerge_array($src, array(
    array(0, 0, TEST_FILE2),
    array(10, 10, TEST_FILE3),
    array(20, 20, TEST_FILE4),
    array(30, 30, TEST_FILE5),
    array(40, 0, TEST_FILE6),
    array(30, 10, TEST_FILE7),
    array(20, 20, TEST_FILE8)
    ));

    mb_http_output("pass");
    header("Content-Type: image/png");
    imagepng($src);
    imagedestroy($src);
    のようになります。imagecopymerge_array()に指定する画像ファイルと配置位置を指定できるようにしました。アルファ透過性を指定するpctを指定できるようにしてもいいかもしれません。
  • id:t_yasu
    tobeoscontinue様

    ありがとうございます。
    画像を合成する度にメモリを解放するみたいな感じですね。
    試してみます。

    配列をつかう方法も有り難うございます。
    私はまだまだ理解するには遠い感じですが、頑張ってみようと思います。
    ありがとうございました。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません