Resize image - Keep proportion - Add white background - php

I want to resize my images to a square. Say I want a squared image of 500x500 and I have an image of 300x600
I want to resize that image down to 200x500 and then add a white background to it to make it 500x500
I got something working good by doing this:
$TargetImage = imagecreatetruecolor(300, 600);
imagecopyresampled(
$TargetImage, $SourceImage,
0, 0,
0, 0,
300, 600,
500, 500
);
$final = imagecreatetruecolor(500, 500);
$bg_color = imagecolorallocate ($final, 255, 255, 255)
imagefill($final, 0, 0, $bg_color);
imagecopyresampled(
$final, $TargetImage,
0, 0,
($x_mid - (500/ 2)), ($y_mid - (500/ 2)),
500, 500,
500, 500
);
It's doing almost EVERYTHING right. The picture is centered and everything. Except the background is black and not white:/
Anyone know what I'm doing wrong?

I think this is what you want:
<?php
$square=500;
// Load up the original image
$src = imagecreatefrompng('original.png');
$w = imagesx($src); // image width
$h = imagesy($src); // image height
printf("Orig: %dx%d\n",$w,$h);
// Create output canvas and fill with white
$final = imagecreatetruecolor($square,$square);
$bg_color = imagecolorallocate ($final, 255, 255, 255);
imagefill($final, 0, 0, $bg_color);
// Check if portrait or landscape
if($h>=$w){
// Portrait, i.e. tall image
$newh=$square;
$neww=intval($square*$w/$h);
printf("New: %dx%d\n",$neww,$newh);
// Resize and composite original image onto output canvas
imagecopyresampled(
$final, $src,
intval(($square-$neww)/2),0,
0,0,
$neww, $newh,
$w, $h);
} else {
// Landscape, i.e. wide image
$neww=$square;
$newh=intval($square*$h/$w);
printf("New: %dx%d\n",$neww,$newh);
imagecopyresampled(
$final, $src,
0,intval(($square-$newh)/2),
0,0,
$neww, $newh,
$w, $h);
}
// Write result
imagepng($final,"result.png");
?>
Note also, that if you want to scale down 300x600 to fit in 500x500 whilst maintaining aspect ratio, you will get 250x500 not 200x500.

Related

Place an image to the center of another image using PHP GD

I need to place an image to the center of another image(both horizontally and vertically) with dimension 700*350. I'm trying with the following code. But I'm getting image as stretched.
#header("Content-Type: image/png");
$imageURL = "flower.jpg";
// create a transparent background image for placing the $imageURL image
$imageResource = imagecreatetruecolor(700, 350);
imagesavealpha($imageResource, true);
$transparentColor = imagecolorallocatealpha($imageResource, 0, 0, 0, 127);
imagefill($imageResource, 0, 0, $transparentColor);
$backgroundImage = imagecreatefromjpeg($imageURL);
list($width, $height) = getimagesize($imageURL);
imagecopyresampled($imageResource, $backgroundImage, 350, 175, 0, 0, 700, 350, $width, $height);
imagepng($imageResource, "newimage.jpg");
This is not centering the image and also the file flower.jpg is getting deleted when I run this code. What I'm doing wrong in this?
Can anyone please help me to fix this? Thanks in advance.
So you need something like this?
#header("Content-Type: image/png");
$imageURL = "flower.jpg";
// create a transparent background image for placing the $imageURL image
$imageResource = imagecreatetruecolor(700, 350);
imagesavealpha($imageResource, true);
$transparentColor = imagecolorallocatealpha($imageResource, 0, 0, 0, 127);
imagefill($imageResource, 0, 0, $transparentColor);
$backgroundImage = imagecreatefromjpeg($imageURL);
list($width, $height) = getimagesize($imageURL);
imagecopyresampled($imageResource, $backgroundImage, 175, 85, 0, 0, 350, 175, $width, $height);
imagepng($imageResource, "newimage.jpg");
imagedestroy($imageResource);
imagedestroy($backgroundImage);
You had specified the center of the destination image as the destination coordinates and the whole destination image size instead of needed dimentions of the center rectangle into which the source image would be resized.
Also you didn't do imagedestroy, which you totally should.

Trouble preserving transparency when resizing image that was a jpg

We get a jpg that contains a drawing made of black lines. We do crop it, rotate it, make the white transparent, then finally resize it to a standard width.
Before I resize it, the image (in $src) is just what I want it to be with transparency in the right places. After resampling it, the image ($out) is back to having a white background. (The commented out lines are some of the things I tried.) Before I found an answer to a similar problem, I wasn't changing the settings for alpha blending and alpha save and there was at least some very noisy transparency.
How can I get the resampled image to change the white to transparent?
EDIT: In $out I see that most pixels are 255, 255, 255. Some are 252, 252, 252. A few are 245, 245, 245. Those are the only 3 values I have seen in $out. I'm not understanding why this would be the case for $out but not for $src.
<?php
$imgname = "../assets/Sample.jpg";
$src = imagecreatefromjpeg($imgname);
$src = imagecropauto($src, IMG_CROP_WHITE);
$white = imagecolorallocate($src, 255, 255, 255);
imagecolortransparent($src, $white);
$src = imagerotate($src, -90, 0);
// Resample
$width = imagesx($src);
$height = imagesy($src);
$percent = 270/$width;
$new_width = $width * $percent;
$new_height = $height * $percent;
$out = imagecreatetruecolor($new_width, $new_height);
//imagefill($out, 0,0, imagecolorallocate($out, 255, 255, 255));
imagealphablending( $out, false );
imagesavealpha( $out, true );
imagecopyresampled($out, $src, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
$white2 = imagecolorallocate($out, 255, 255, 255);
imagecolortransparent($out, $white2);
header("Content-type: image/png");
// imagepng($src);
imagepng($out);
?>
The problem with drawing in JPEG is that the compression process slightly changes values. This is not generally noticeable in photos but shows up in drawings.
If you know everything is black or write, you should convert the pixels that are close-to-black to black and those that are close-to-white to white.

php merge image with it own fliped and rotated view at different positions

i want to merge image with it own flipped image and rotated at angle say -60 degree.
Suppose i have image of 1000*1000 px then
A: original image resized to 500*500px and places in right bottom part of 1000*1000 square box
B:same image a flipped and rotated by -600 degree and place in top left corner of 1000*1000 square box
everything works fine but just issue like
1: some border for rotated images
2: background on rotate one is more darker make it look bid odd
test case :
sample image (thumbnail is resized, click to open original image) :
output image :
Below is my code
$image1=$image2=imagecreatefrompng('a.png');
//filter_opacity( $image1, 25 );
$w=imagesx($image1);
$h=imagesy($image1);
$finala = imagecreatetruecolor($w, $h);
$finalb = imagecreatetruecolor($w, $h);
$finalc = imagecreatetruecolor($w, $h);
$backgroundColora = imagecolorallocate($finala, 250,252,252); // gray
$backgroundColorb = imagecolorallocate($finalb, 250,250,250); // gray
$backgroundColorc = imagecolorallocate($finalc, 250,250,250); // gray
imagefill($finala, 0, 0, $backgroundColora);
imagefill($finalb, 0, 0, $backgroundColorb);
imagefill($finalc, 0, 0, $backgroundColorc);
$percent = 0.583;
$new_width = $w * $percent;
$new_height = $h * $percent;
$wshift = $w/8.5;
$hshift = $h/2.5;
imagecopy($finala, $image1, 0,0,0,0,$w,$h);
imagecopyresampled($finala, $image2,$wshift,$hshift,0,0, $new_width, $new_height, $w, $h);
imagecopy($finalc, $image1, 0,0,0,0,$w,$h);
imagecopyresampled($finalc, $image2,$wshift,$hshift,0,0, $new_width, $new_height, $w, $h);
imagecopyresampled($finalb, $finalc,$w*0.3,$h*0.3,0,0, $w*0.6, $h*0.6, $w, $h);
imageflip($finala, IMG_FLIP_HORIZONTAL );
$finala = imagerotate($finala, -60, imageColorAllocateAlpha($finala, 0, 0, 0, 127));
imagecopyresampled($finalb, $finala,-$w*0.1,-$h*0.1,0,$h*0.20, $new_width, $new_height, $w, $h);
header('Content-Type: image/jpeg');
imagejpeg($finalb);
imagedestroy($finala);
imagedestroy($image2);
imagedestroy($image1);
imagedestroy($final);
As you need to rotate and place same image at top and bottom, you no need to pass same image twice with $_GET single time is enough
// Source image
$image = imagecreatefrompng("test.png");
$w=imagesx($image);
$h=imagesy($image);
$finalImage = imagecreatetruecolor($w, $h);
// Bg add
$backgroundColor = imagecolorallocate($finalImage, 252,252,252); // gray
imagefill($finalImage, 0, 0, $backgroundColor);
// New sizes calculation
$percent = 0.5;
$new_width = $w * $percent;
$new_height = $h * $percent;
// First image add
imagecopyresampled($finalImage, $image, $new_width, $new_height, 0, 0,
$new_width, $new_height, $w, $h);
// Second image rotate with transparant bg
$transparency = imagecolorallocatealpha( $image,0,0,0,127 );
$rotatedImage = imagerotate( $image, -60, $transparency, 1);
imagealphablending( $rotatedImage, false );
imagesavealpha( $rotatedImage, true );
// Getting new rotated image sizes to avoid cutting border
$rw = imagesx($rotatedImage);
$rh = imagesy($rotatedImage);
// Second rotated image add with bigger space
imagecopyresampled($finalImage, $rotatedImage, 0, 0, 0, 0,
$rw*$percent, $rh*$percent, $rw, $rh);
// Outputing png image
header( 'Content-Type: image/png' );
imagepng( $finalImage );
change this line:
$finala = imagerotate($finala, -60, imageColorAllocateAlpha($finala, 0, 0, 0, 127));
to
$finala = imagerotate($finala, -60, imageColorAllocateAlpha($finala, 250, 252, 252, 127));
the black board should gone!

Copy one image on top of the next, while retaining transparency

I'm struggling with PHP's GDLib just a little bit here. I'm trying to overlay two .PNG images on top of eachother, which so far works fine.
The one problem I run into is that sometimes, the overlay image comes with a white background. I can make this transparent (using the imagecolortransparent function), but this transparency isn't saved when I copy this image onto a new one.
// Load the background image first
$background = imagecreatefrompng($this->background);
// Load the overlaying image next, and set white as a transparent color
$overlay = imagecreatefrompng($this->image);
imagecolortransparent($overlay, imagecolorallocate($overlay, 255, 255, 255));
// So far, this all works. But when I create a new image,
// and paste both $background and $overlay into it,
// $overlay loses transparency and reverts to a white fill.
$image = imagecreatetruecolor(16, 16);
imagesavealpha($image, true);
$trans_colour = imagecolorallocatealpha($image, 255, 255, 255, 127);
imagefill($image, 0, 0, $trans_colour);
imagecopyresampled($image, $background, 0, 0, 0, 0, 16, 16, 16, 16);
imagecopyresampled($image, $overlay, 0, 0, 0, 0, 16, 16, 16, 16);
#mkdir(dirname($file), 0777, true);
imagepng($image, $file);
// The new $image is now mostly white. The transparency on $overlay
// was lost, meaning that the $background image is completely invisible.
How can I keep the transparency when copying $overlay into a new image?
$photo_to_paste = "photo_to_paste.png";
$white_image = "white_image.png";
$im = imagecreatefrompng($white_image);
$im2 = imagecreatefrompng($photo_to_paste);
imagecopy($im, $im2, (imagesx($im) / 2) - (imagesx($im2) / 2), (imagesy($im) / 2) - (imagesy($im2) / 2), 0, 0, imagesx($im2), imagesy($im2));
// Save alpha for the destination image.
imagesavealpha($im, true);
$trans_colour = imagecolorallocatealpha($im, 0, 0, 0, 127);
imagefill($im, 0, 0, $trans_colour);
// Save final image after placing one on another image
imagepng($im, "output.png", 0);
imagedestroy($im);
imagedestroy($im2);

How to delete transparent color in images?

What is the best way to replace transparent colors with white in gif and png images with php?
// get transparent color indexes
$trsp = ImageColorsForIndex($image, ImageColorTransparent($image));
// get transparent color set
$delete = imagecolorallocate($image, $trsp['red'], $trsp['green'], $trsp['blue']);
// replace
imagecolorset($image, $delete, 255, 255, 255);
does not working.
I don't really use GD all that much - I prefer ImageMagick. The following method works, but I'm not sure if it is the most efficient:
// Get the original image.
$src = imagecreatefrompng('trans.png');
// Get the width and height.
$width = imagesx($src);
$height = imagesy($src);
// Create a white background, the same size as the original.
$bg = imagecreatetruecolor($width, $height);
$white = imagecolorallocate($bg, 255, 255, 255);
imagefill($bg, 0, 0, $white);
// Merge the two images.
imagecopyresampled(
$bg, $src,
0, 0, 0, 0,
$width, $height,
$width, $height);
// Save the finished image.
imagepng($bg, 'merged.png', 0);

Categories