2013-03-23 31 views
10

Tworzę awatary z PHP GD. Denerwująca przestrzeń między nogami awatara i dnem obrazu. Chcę ewentualnie pozbyć się tej przestrzeni, "popychając" awatar w dół (patrz poniżej).Przenoszenie obrazu na dno

Oto oryginalny obraz, że nie lubię, obok obrazu chcę uzyskać:

enter image description here

Czy istnieje sposób na to? Dzięki. Poniżej znajduje się główna część kodu używanego do generowania obrazu.

$assets = array(
    "../assets/shirt/Default.png", 
    "../assets/body/Default.png", 
    "../assets/hair/Default.png", 
    "../assets/eyes/Default.png", 
    "../assets/eyebrows/Default.png", 
    "../assets/mouth/Default.png", 
    "../assets/pants/Default.png" 
); 

$baseImage = imagecreatefrompng($assets[0]); 
imagealphablending($baseImage, true); 
imagesavealpha($baseImage, true); 

foreach($assets as $item) { 
    $newImage = imagecreatefrompng($item); 
    imagecopy($baseImage, $newImage, 0, 0, 0, 0, 350, 550); 

    imagealphablending($baseImage, true); 
    imagesavealpha($baseImage, true); 
} 

if($_GET['x']) { 

    $sizex = $_GET['x']; if($sizex > 350) $sizex = 350; 
    $sizey = $_GET['y']; if($sizey > 550) $sizey = 550; 

    $png = imagecreatetruecolor($sizex, $sizey); 
    imagesavealpha($png, true); 

    $trans_colour = imagecolorallocatealpha($png, 0, 0, 0, 127); 
    imagefill($png, 0, 0, $trans_colour); 

    $blankImage = $png; 
    imagealphablending($blankImage, true); 
    imagesavealpha($blankImage, true); 

    imagecopyresampled($blankImage, $baseImage, 0, 0, 0, 0, $sizex, $sizey, 350, 550); 

    header("Content-type: image/png"); 
    imagepng($blankImage); 
} 
else { 
    header("Content-type: image/png"); 
    imagepng($baseImage); 
} 

Uwaga: if($_GET['x']) { część tego kodu jest umożliwienie mi generować różne rozmiary awatara na miejscu. To działa dobrze.

+0

Trudno zrozumieć pytanie, ale dlaczego nie zmniejszyć wysokość płótna przez na piksel? –

+0

Zaktualizowano w/zdjęcia i lepsze wyjaśnienie. Jestem okropny w wyjaśnianiu rzeczy. Przepraszam. :( – Anonymous

+0

@BenD Nie mogę zmienić rozmiaru obrazu, a to dlatego, że użytkownik może dodać zestaw butów lub coś, co mogłoby wykorzystać to miejsce. – Anonymous

Odpowiedz

3

Oto kod do przycinania dołu i przesuwania przyciętego obrazu do dołu.

<?php 
example(); 
function example(){ 
    $img = imagecreatefrompng('http://i.stack.imgur.com/UUiMK.png'); 
    imagealphablending($img, true); 
    imagesavealpha($img, true); 

    // copy cropped portion 
    $img2 = imageCropBottom($img); 

    // output cropped image to the browser 
    header('Content-Type: image/png'); 
    imagepng($img2); 

    imagedestroy($img2); 
} 

function imageCropBottom($image) { 
    $background1 = imagecolorat($image, 0, 0); 
    $background2 = imagecolorat($image, 1, 1); 

    $imageWidth = imageSX($image); 
    $imageHeight = imageSY($image); 
    $bottom = 0; 

    for ($y = $imageHeight ; $y > 0 ; $y--) { 
     for ($x = 0 ; $x < imagesx($image) ; $x++) { 

      $imageColor = imagecolorat($image, $x, $y); 
      if (($imageColor != $background1) && ($imageColor != $background2)) { 
       $bottom = $y; 
       break; 
      } 
     } 
     if ($bottom > 0) break; 
    } 

    $bottom++; 

    // create new image with padding 
    $img = imagecreatetruecolor($imageWidth, $imageHeight); 
    imagealphablending($img, true); 
    imagesavealpha($img, true); 

    $trans_colour = imagecolorallocatealpha($img, 0, 0, 0, 127); 
    imagefill($img, 0, 0, $trans_colour); 

    // copy 
    imagecopy($img, $image, 1, $imageHeight-$bottom, 1, 1, $imageWidth-2, $bottom-1); 

    // Draw a black rectangle 
    $black = imagecolorallocate($img, 0, 0, 0); 
    imagerectangle($img, 0, 0, $imageWidth-1, $imageHeight-1, $black); 


    // destroy old image cursor 
    imagedestroy($image); 
    return $img; 
} 

Referencje:

2

Myślę, że rozwiązaniem jest zbudowanie awatara w trybie bottom-up. czyli buty -> spodnie -> shirt -> twarz -> włosy

(pseudo-code)

position = (x,y) // where y is the height of the canvas initially 
if(need(shoe)){ 
    position = position - shoe.height 
    add shoe at position 
} 
if(need(pant)) { 
    position = position - pant.height 
    add pant at position 
} 
... and so on 

Jeśli spojrzeć na metody imagecopy to ma metoda po podpisaniu

bool imagecopy (resource $dst_im , resource $src_im , int $dst_x , int $dst_y , int $src_x , int $src_y , int $src_w , int $src_h) 

Zmieniając $dst_x i $dst_y, możesz osiągnąć to, co opisałem.

+0

Jest to jednak kłopotliwe, ponieważ buty mogą mieć różną wysokość Wszelkie sugestie na ten temat: – Anonymous

+0

Użyj getimagesize(), aby dynamicznie określić wysokość lub zmienić tablicę aktywów do zagnieżdżonego hasha, który ma wszystkie niezbędne parametry. – Josnidhin