Extend image canvas with GD or Imagick - php

Let's say I have an 200x100 image, and I resize it to 100x50:
// imagick
$imagick->resizeImage($width, $height, Imagick::FILTER_UNDEFINED, 1)
// gd
$image = imagecreatetruecolor($width, $height);
imagecopyresampled($image, $src, 0, 0, 0, 0, $width, $height, imagesx($src), imagesy($src)))
But I want the image to be 120x120. How can extend the canvas to that size, but keep that image I just resized in the same dimensions, in the center? Something like Image->Canvas Size in Photoshop

// make the canvas, fill it with $color
$canvas = imagecreatetruecolor(120, 120);
imagefilledrectangle($canvas,0,0,120,120,$color);
// get the image from file...
list($width, $height) = getimagesize('myimage.jpg');
$img = getimagefromjpg('myimage.jpg');
// resample image and place it in center of canvas
$x = intval(($width - 100) / 2);
$y = intval(($height - 50) / 2);
imagecopyresampled($canvas, $img, $x, $y, 0, 0, 100, 50, $width, $height);
// output etc. ...

Related

How can I add shadow to an image using the PHP GD library?

I have created a script where I am placing an image in the center of another image using the PHP GD library. After that I've placed a PNG frame above that center placed image.
I now want to a give that image a 3D effect, or some shadow around the edges will work for me. How can I do that ?
// Get Product Image sizes
list($width, $height) = getimagesize($filename);
// Load
$source = imagecreatefromjpeg($filename);
// Output
if(isset($frame_image) && !empty($frame_image))
{
$png = imagecreatefrompng($frame_image);
list($newwidthf, $newheightf) = getimagesize($frame_image);
$out = imagecreatetruecolor($width, $height);
imagecopyresampled($out, $source, 0, 0, 0, 0, $width, $height, $width, $height);
imagecopyresampled($out, $png,0, 0, 0, 0, $width, $height, $newwidthf, $newheightf);
$final = imagejpeg($out);
}
else
{
$final = imagejpeg($source);
}
Here is the image which I have generated:
I'm using imagescale and a shadow background, work

Image color changed with imagecreate in php

I have to create dynamic student card image. add put this image object in student profile photo. But, student image color are changed.
How to put student profile photo with original color?
Here is my code:
header("Content-Type: image/jpeg");
$im = #imagecreate(602, 980)
or die("Cannot Initialize new GD image stream");
$background_color = imagecolorallocate($im, 255, 255, 255);
$card_header = imagecreatefromjpeg('img/card/card-header.jpg');
imagecopy($im, $card_header, 0, 0, 0, 0, 602, 253);
$card_footer = imagecreatefromjpeg('img/card/card-footer.jpg');
imagecopy($im, $card_footer, 0, 834, 0, 0, 602, 146);
$student_photo = 'img/card/girls-profile.jpg'; //imagecreatefromjpeg($studentlist[0]->getCardPhoto());
// Get new sizes
list($width, $height) = getimagesize($student_photo);
$newwidth = 180;
$newheight = 220;
// Load
$thumb = imagecreatetruecolor($newwidth, $newheight);
$source = imagecreatefromjpeg($student_photo);
// Resize
imagecopyresized($thumb, $source, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
imagecopy($im, $thumb, 220, 220, 0, 0, $newwidth, $newheight);
imagejpeg($im, "uploads/card/test.jpeg");
imagedestroy($im);
Header Img:
Footer Img:
Profile Img:
Here is my output image:
Main problem is that your $im needs to be a true color image as well.
Secondly, you have to actually fill your background.
You can also skip creating $thumb and copyresized directly into your $im.
Heres a working verison (i changed your paths to test it on my machine)
<?php
header('Content-Type: image/jpeg');
$im = #imagecreatetruecolor(602, 980) // you want to create a truecolorimage here
or die("Cannot Initialize new GD image stream");
$background_color = imagecolorallocate($im, 255, 255, 255);
imagefill($im, 0, 0, $background_color); // you have to actually use the allocated background color
$card_header = imagecreatefromjpeg('card-header.jpg');
imagecopy($im, $card_header, 0, 0, 0, 0, 602, 253);
$card_footer = imagecreatefromjpeg('card-footer.jpg');
imagecopy($im, $card_footer, 0, 834, 0, 0, 602, 146);
$student_photo = 'girls-profile.jpg';
// Get new sizes
list($width, $height) = getimagesize($student_photo);
$newwidth = 180;
$newheight = 220;
// Load
//$thumb = imagecreatetruecolor($newwidth, $newheight); // you can skip allocating extra memory for a intermediate thumb
$source = imagecreatefromjpeg($student_photo);
// Resize
imagecopyresized($im, $source, 220, 220, 0, 0, $newwidth, $newheight, $width, $height); // and copy the thumb directly
imagejpeg($im);
imagedestroy($im);
// you should also destroy the other images
imagedestroy($card_header);
imagedestroy($card_footer);
imagedestroy($source);
Keep in mind that your profile picture current gets distorted though, you may wan't to either make sure the profile pictures always have the correct aspect ratio or you may want to crop the image. See here for more details: PHP crop image to fix width and height without losing dimension ratio

PHP increase image resolution from url and then crop

I have images with resolution of 720x1280 and I would need to store them on server with resolution 800x1500.
Since 720x1280 increased to height 1500 gives resolution of 844x1500 I would also need to crop image, remove 22 pixels from the left and right side.
For now I have this:
$img_url = file_get_contents($url);
$img = imagecreatefromstring($img_url);
$width = imagesx($img);
$height = imagesy($img);
$new_width = '800';
$new_height = '1500';
$thumb = imagecreatetruecolor($new_width, $new_height);
imagecopyresampled($thumb, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
imagejpeg($thumb, $name, 100);
imagedestroy($thumb);
imagedestroy($img);
But the problem is that image is not cropped, 22 pixels from the left and right side are not removed.
Is there a way to do this, to first increase image resolution from url and then crop?
Googling php image crop reveals the secret:
$rect = [22, 0, 800, 1500]
$thumb = imagecrop($thumb, $rect)
In this line:
imagecopyresampled($thumb, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
you just scale your original image to new dimensions.
As the documentation says:
If the source and destination coordinates and width and heights differ, appropriate stretching or shrinking of the image fragment will be performed.
You need to set:
$shiftX = 22*(1280/1500); // consider passing variables rather than constant values
$scaledWidth = 720-$shiftX*2;
imagecopyresampled($thumb, $img, 0, 0, $shiftX, 0, $new_width, $new_height, $scaledWidth, $height);
which cuts out the required (proportional) rectangle of the source image to paste it in you destination picture.

Center watermark text on image when unknown size of text

I'm trying to create an image with a watermark text in it and I want it to be central on the image. The text I want to watermark can be anywhere from 5 characters to 15 characters, therefore I cannot put a final size for the text to fit every image.
This is the code I use to create the watermarked image
function watermarkImage ($SourceFile, $WaterMarkText, $DestinationFile) {
list($width, $height) = getimagesize($SourceFile);
$image_p = imagecreatetruecolor($width, $height);
$image = imagecreatefromjpeg($SourceFile);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width, $height);
$black = imagecolorallocate($image_p, 0, 0, 0);
$font = '../fonts/proxima-nova-light.otf';
$font_size = 100;
imagettftext($image_p, $font_size, 0, 303, 190, $black, $font, $WaterMarkText);
if ($DestinationFile<>'') {
imagejpeg ($image_p, $DestinationFile, 100);
} else {
header('Content-Type: image/jpeg');
imagejpeg($image_p, null, 100);
};
imagedestroy($image);
imagedestroy($image_p);
};
Which does an excellent job on some texts but when I try it on longer texts it looks bad.
I want to - somehow - calculate the optimal size of text and choose size, x and y from there.
Any ideas?
After doing some research with help from #Sammitch I was able to figure it out. Here is the working code:
<?php
function watermarkImage ($SourceFile, $WaterMarkText, $DestinationFile) {
$font = 'fonts/your-font-here.ttf';
$font_size = 40;
list($width, $height) = getimagesize($SourceFile);
$image_p = imagecreatetruecolor($width, $height);
$image = imagecreatefromjpeg($SourceFile);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width, $height);
$black = imagecolorallocate($image_p, 0, 0, 0);
$bbox = imagettfbbox($font_size, 0, $font, $WaterMarkText);
$x = $bbox[0] + (imagesx($image) / 2) - ($bbox[4] / 2) + 10;
$y = $bbox[1] + (imagesy($image) / 2) - ($bbox[5] / 2) - 5;
imagettftext($image_p, $font_size, 0, $x, $y, $black, $font, $WaterMarkText);
if ($DestinationFile<>'') {
imagejpeg ($image_p, $DestinationFile, 100);
} else {
header('Content-Type: image/jpeg');
imagejpeg($image_p, null, 100);
};
imagedestroy($image);
imagedestroy($image_p);
};
?>
Calculate the position of the watermark in the output image (the
watermark shall be placed in the Center of the Image)
$watermark_pos_x = (imagesx($image)/2) - (imagesx($watermark)/2) - 15;
$watermark_pos_y = (imagesy($image)/2) - (imagesy($watermark)/2) - 10;
Use this value on function.

PHP Resize image and save Transparent PNG

I've a png image uploading script in my website and i'm scaling down the large images to small size and i'm using this code but it loses the transparent background
$image = $tmp; // Uploaded Image
$maxImgWidth = 224;
$src = imagecreatefrompng($image);
list($width, $height) = getimagesize($image);
$newwidth = $maxImgWidth;
$newheight = ($height / $width) * $newwidth;
$newImage = imagecreatetruecolor($newwidth, $newheight);
imagealphablending($image, true);
imagesavealpha($image, true);
imagecopyresampled($newImage, $src, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
imagepng($newImage, "../thumb/$name_after-$code.$ext", 1);
imagedestroy($src);
imagedestroy($newImage);
This code makes the image without transparency :
And i want with transparent background like this one :
Sorry I have no experience in PHP but after I read this page, I think you may need add the transparent colour after you set the save alpha is true
imagesavealpha($image, true);
$color = imagecolorallocatealpha($image, 0, 0, 0, 127);
imagefill($image, 0, 0, $color);
if still cannot try add this after imagecolorallocatealpha(),
imagecolortransparent($image, $color);

Categories