Search code examples
phpimagegdmovepixel

Moving an image to the bottom


I am making avatars with PHP GD. There's annoying space between the avatar's feet, and the bottom of the image. I want to possibly get rid of that space by "pushing" the avatar down to the bottom (see below).

Here's the original image that I don't like, alongside the image I want to get:

enter image description here

Is there a method to this? Thanks. Below is the main part of the code being used for image generation.

$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);
}

Note: The if($_GET['x']) { part of that code is to allow me to generate different sizes of the avatar on the spot. It works fine.


Solution

  • Here is the code to crop the bottom and move the cropped image to bottom.

    <?php
    example();
    function example(){
        $img = imagecreatefrompng('https://i.sstatic.net/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;
    } 
    

    References: