Собрать PNG изображение по фрагментам

Встала задача: собрать изображение из фрагментов. Все фрагменты - png картинки.
Каждая картинка характеризуется как координата смещения (т.е. координата верхнего угла на итоговом изображении), отображать и/или поворачивать, путь к изображению.




//создать прозрачную картинку
function gd_create(&$im, $width, $height)
{
    $im = @imagecreatetruecolor($width, $height)
        or die("Невозможно создать поток изображения");
    $transparent = imagecolorallocatealpha($im, 0, 0, 0, 127);
    imagefill($im, 0, 0, $transparent);
    imagesavealpha($im, true);
}

/**
 * Сборка изображения из фрагментов и сохраняем изображение в  $avafilename
 * @param $mimg_str
 */
function gd_complete($mimg_str, $avafilename)
{
    global $GD_IMG_URL;
    $images = gd_parse_mimg($mimg_str);
    if(!$images)
        return false;
    //dump('COMPLETE');
    $n=count($images);
    $baseW = 0;
    $baseH = 0;
    $cutX = null;  //минимальное смещение по X => отрезать от собранной картинки по X
    $cutY = null;  // .. по Y
    for($i=0;$i<$n;$i++)
    {
        $url = $GD_IMG_URL.$images[$i]['img'] ; //получаем абсолютный путь к изображению
        //dump($url);
        $images[$i]['tmp'] = tempnam("tmp", "gd");
        $savefile = fopen($images[$i]['tmp'], 'w');
        fwrite($savefile, file_get_contents($url));
        fclose($savefile);
        $isize = getimagesize($images[$i]['tmp']);
        if(!$isize)
        {
            unset($images[$i]);
            continue;
        }
        $images[$i]['width'] = $isize[0];
        $images[$i]['height'] = $isize[1];
        $images[$i]['mime'] = $isize['mime'];

        $imgW = $images[$i]['x']+$images[$i]['width'];
        if($baseW<$imgW)
            $baseW = $imgW;
        $imgH = $images[$i]['y']+$images[$i]['height'];
        if($baseH<$imgH)
            $baseH = $imgH;

        if(is_null($cutX))
            $cutX = $images[$i]['x'];
        elseif($cutX > $images[$i]['x'])
            $cutX = $images[$i]['x'];
        if(is_null($cutY))
            $cutY = $images[$i]['y'];
        elseif($cutY > $images[$i]['y'])
            $cutY = $images[$i]['y'];

    }
//   dump($images);
/*Array(
      [0] => Array
          (
                [mimg] => 7 2 2 getimg.php?id=12076&type=1
                [x] => 7
                [y] => 2
                [transform] => 2
                [img] => getimg.php?id=12076&type=1
                [tmp] => /var/www/html/pm/mobile/tmp/gd1CZnxu
                [width] => 17
                [height] => 23
                [mime] => image/png
          )

     [1] => Array
          (
                [mimg] => 4 1 2 getimg.php?id=12668&type=1
                [x] => 4
                [y] => 1
                [r] => 2
                [img] => getimg.php?id=12668&type=1
                [tmp] => /var/www/html/pm/mobile/tmp/gd0mCcDj
                [width] => 22
                [height] => 27
                [mime] => image/png
          )
)*/
//    die();

    gd_create($im, $baseW+1, $baseH);

    foreach($images as $i=>$img)
    {
        $src = imagecreatefrompng ($img['tmp']);
        $transform = gd_transform($img['transform']);

        //TODO: пересчитать размеры если есть поворот!!
        /*if(getElement($transform,'rotation'))
        {
            $bgd_color = 0;
            imagerotate ( $src , $transform['rotation'] , $bgd_color  )
        }*/

        if(getElement($transform,'flipX'))
            gd_mirror($im, $src,  $img['x'], $img['y'],$img['width'], $img['height']);
        else
            imagecopy($im, $src, $img['x'], $img['y'], 0, 0, $img['width'], $img['height']);
        imagedestroy($src);
     // if($i>=5)
     //   break;
    }

    //обрезаем лишнее
    $cutW = $baseW+1-$cutX;
    $cutH = $baseH-$cutY;
    gd_create($imcut, $cutW, $cutH);
    imagecopyresampled ($imcut , $im , 0 , 0 , $cutX , $cutY , $cutW, $cutH , $cutW, $cutH );
    //-------------------------------------------------------------
    $n=count($images);
    for($i=0;$i<$n;$i++)
    {
        unlink($images[$i]['tmp']);
    }
    imagepng($imcut,$avafilename);
    imagedestroy($im);
    imagedestroy($imcut);
   /* ob_clean();
    header("Content-Type: image/png");
    //imagepng($im);
    imagepng($imcut);
    imagedestroy($im);
    imagedestroy($imcut);
    die();*/
    return true;
}


function gd_mirror(&$new_image, &$image, $offset_x=0, $offset_y=0, $width, $height)
{

    $dst_y = 0;
    $src_y = 0;

    //$coordinate = ($width - 1);
    $coordinate = ($width - 1);

    foreach(range($width-1, 0) as $range)
    {
        $src_x = $range;
        $dst_x = $coordinate - $range;

        ImageCopy($new_image, $image, $dst_x+$offset_x, $dst_y+$offset_y, $src_x, $src_y, 1, $height);
    }
}

//получить применяемые изменения
function gd_transform($type)
{
    $flipX = null;
    $rotation = null;
    switch ($type) {
        case 1: //TRANS_MIRROR_ROT180
            $flipX = YES;
            $rotation = 180;
            break;
        case 2: //TRANS_MIRROR
            $flipX = YES;
            break;
        case 3: //TRANS_ROT180
            $rotation = 180;
            break;
        case 4: //TRANS_MIRROR_ROT270
            $flipX = YES;
            $rotation = 270;
            break;
        case 5: //TRANS_ROT90
            $rotation = 90;
            break;
        case 6: //TRANS_ROT270
            $rotation = 270;
            break;
        case 7: //TRANS_MIRROR_ROT90
            $flipX = YES;
            $rotation = 90;
            break;
        default://no transformation
            break;
    }
    return array('flipX'=>$flipX, 'rotation'=>$rotation);
}

Комментарии

  1. Ответы
    1. Это ты к чему? Через массивы быстрее работать будет?

      Удалить
    2. Нет, этот вариант даже медленней, но код изящнее. Если хочется, чтобы на массивах было быстрей, чем через switch (при множестве вызовов функции, к примеру), надо инициализацию один раз делать. Будет быстрей.

      Удалить
    3. с последним согласна на все 100!

      Удалить

Отправить комментарий

Популярные сообщения