Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 870
Anonymous Avatar asked Mar 23 '13 15:03

Anonymous


People also ask

How do I move an image to the bottom in CSS?

If position: absolute; or position: fixed; - the bottom property sets the bottom edge of an element to a unit above/below the bottom edge of its nearest positioned ancestor. If position: relative; - the bottom property makes the element's bottom edge to move above/below its normal position.


2 Answers

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

<?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;
} 

References:

  • Crop whitespace from image in PHP
  • http://www.php.net/manual/en/function.imagecopy.php#97836
like image 181
Rully Hendrawan Avatar answered Oct 18 '22 20:10

Rully Hendrawan


I think the solution is to build the avatar in a bottom-up fashion. i.e. shoe -> pant -> shirt -> face -> hair

(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

If you look at the imagecopy method it has the following method signature

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 )

By varying $dst_x and $dst_y you could achieve what I have described.

like image 2
Josnidhin Avatar answered Oct 18 '22 19:10

Josnidhin