PHP GD Cropping Images

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
Teonnyn
Forum Commoner
Posts: 58
Joined: Tue Dec 23, 2008 4:07 am

PHP GD Cropping Images

Post by Teonnyn »

I'm trying to fit an avatar into a set area - however, there is already one major problem. All of the avatars are square, while the space they have to be fitted onto has rounded corners. Using GD Library, I tried adding rounded corners to the image but it didn't help much so cropping seems to be the next best option - does anyone know of how to do this with GD? ImageMagick is out of the question - my host does not run it, and I am on a Shared Server so can't install it myself.
User avatar
Skara
Forum Regular
Posts: 703
Joined: Sat Mar 12, 2005 7:13 pm
Location: US

Re: PHP GD Cropping Images

Post by Skara »

imagecopyresampled()
bool imagecopyresampled ( resource $dst_image , resource $src_image , int $dst_x , int $dst_y , int $src_x , int $src_y , int $dst_w , int $dst_h , int $src_w , int $src_h )
I've never done this before, so hopefully my logic is sound...

Create the $dst_image as being square. $dst_x and $dst_y would be the top left of the image (0,0). $dst_w and $dst_h would be the same as the height and width of $dst_image, since we're filling the entire thing.

$src_x and $src_y would be the top left of the crop. $src_w and $src_h would be the distance from the top left to the bottom right of the crop.

That leaves calculating where the crop will be.
If you have an image that is 18x6 pixels, the crop would be 6x6. We know this, but how do we know it? We first know that the crop should be in the middle, so:
$middle = $width / 2;
We next know that the max height and width of the crop is the height (the smallest dimension), so:
$src_w = $src_h = $height;
After that, we need the top left corner of the crop. We know the top is at 0,
$src_y = 0;
and we know that the x value is half the width away from the middle of the crop, so:
$src_x = $middle - ($src_w / 2);

The only thing left is to account for vertical images, where I think we can simply invert x and y.

Code: Select all

//untested!  I hope this is right... ^^;
 
//where $width and $height are the w & h of the original image:
 
if ($width > $height) {
    $middle = $width / 2;
    $src_w = $src_h = $height;
    $src_y = 0;
    $src_x = $middle - ($src_w / 2);
}
elseif ($height < $width) {
    $middle = $height / 2;
    $src_w = $src_h = $width;
    $src_x = 0;
    $src_y = $middle - ($src_h / 2);
}
else { //image is already square
    $src_w = $src_h = $height; //or $width, it doesn't matter..
    $src_x = $src_y = 0;
}
The rest you should be able to figure out yourself.

Edit:
damn. got beaten to it.
User avatar
Skara
Forum Regular
Posts: 703
Joined: Sat Mar 12, 2005 7:13 pm
Location: US

Re: PHP GD Cropping Images

Post by Skara »

...so cropping seems to be the next best option - does anyone know of how to do this with GD?
That's what I was responding to. I was under the impression that rounded corners didn't solve his problem. *shrugs* Now he can do both. :D
Teonnyn
Forum Commoner
Posts: 58
Joined: Tue Dec 23, 2008 4:07 am

Re: PHP GD Cropping Images

Post by Teonnyn »

Thank you to both! I was about to try another solution - "Layers" One white layer as the background, and then put the avatar itself on top of that. Take the "frame" layer, and apply transparency to a color which'll be where the avatar itself goes. Then adjust it so that it fits like this: Background (White), "Avatar" posistioned in the avatar slot attached to the background, Frame Layer set to translucent on white on top of the background.
Teonnyn
Forum Commoner
Posts: 58
Joined: Tue Dec 23, 2008 4:07 am

Re: PHP GD Cropping Images

Post by Teonnyn »

Issue solved! Thinking of this as working with layers helped a LOT! I tried the other two solutions offered and neither really did what I was looking for.

Thinking of the whole thing as a bunch of layers, I first built a simple white background layer in the size needed. The avatar itself was added onto that directly, in the correct position where the "frame" it would be showing through is.

After that, I took the frame and designated "White", 255,255,255, as a transparent color, full transparency. The frame image was added onto the "background/avatar" layer image and set to 100 pct. Everything else required is set on top of the frame and shows up perfectly, most of it being in the white spots.

The only problem is that using this "transparency" method (layering things on top of eachother), a little white line develops between the avatar and the frame image. It's really no big deal, but I was wondering if there was a solution to fix that. While I can't show the entire set of code, I can show what handles the "layering" effect - imagecopymerge is the only one that'll transfer the transparency:

Code: Select all

imagecopyresampled($background,$newavatar,35,145,0,0,262,262,$avwidth,$avheight);
imagecolortransparent($im, $white);
imagecopymerge($background,$im,0,0,0,0,575,1008,100);
Post Reply