PHP Resize image and save Transparent PNG - php

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

Related

Black color at cropped borders when using it in gdi, but looks transparent in photo editor

Borrowed this code to circle crop an image output.
// create the transparent circle image
$filename = APP_WEB_PATH."img/user/".$_GET['img'].".jpg";
$imagefilenamepng = APP_WEB_PATH."img/user/".$_GET['img']."_c.png";
$image_s = imagecreatefromstring(file_get_contents($filename));
$width = imagesx($image_s);
$height = imagesy($image_s);
$newwidth = 300;
$newheight = 300;
$image = imagecreatetruecolor($newwidth, $newheight);
imagealphablending($image, true);
imagecopyresampled($image, $image_s, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
//create masking
$mask = imagecreatetruecolor($newwidth, $newheight);
$transparent = imagecolorallocate($mask, 255, 0, 0);
imagecolortransparent($mask,$transparent);
imagefilledellipse($mask, $newwidth/2, $newheight/2, $newwidth, $newheight, $transparent);
$red = imagecolorallocate($mask, 0, 0, 0);
imagecopymerge($image, $mask, 0, 0, 0, 0, $newwidth, $newheight, 100);
imagecolortransparent($image,$red);
imagefill($image, 0, 0, $red);
imagepng($image,$imagefilenamepng);
imagedestroy($image);
imagedestroy($mask);
The image looks good and transparent and even when opened with a photo editor
but when used inside an image using php GDI i get a black border instead of transparent
what am I missing here.. (if I use paint.net image editor and re-save the image, then it works fine..) the below image works fine after saving in the photo editor
I use the code to call it as
self::$im = imagecreatefromjpeg($imgname1);
$im2 = imagecreatefrompng($imgname2);
$sx = imagesx($im2)*$scale;
$sy = imagesy($im2)*$scale;
$stamp = imagescale($im2, $sx);
imagecopy(self::$im, $stamp, $xcord, $ycord, 0, 0, $sx, $sy);
here self::$im is the larger image, and $im2 is the one that is cropped

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

Extend image canvas with GD or Imagick

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. ...

Combine two PNG transparent images

I'm trying to create a function to resize transparent PNG images and adding a transparent PNG watermark to them. I have tried to place imagealphablending($image_p, false); and imagesavealpha($image_p,true); everywhere, but it it makes black background or crop the first image. Here is my code:
$newName=$this->filename;
list($OrigWidth, $OrigHeight)=$this->info;
if($OrigHeight>$OrigWidth){
$pomer=$OrigWidth/$OrigHeight;
$NewHeight=$h;
$NewWidth=$NewHeight*$pomer;
}else{
$pomer=$OrigHeight/$OrigWidth;
$NewWidth=$w;
$NewHeight=$NewWidth*$pomer;
}
$image_p=imagecreatetruecolor($NewWidth, $NewHeight);
if($this->ext=="jpg")
$image=imagecreatefromjpeg($newName);
elseif($this->ext=="png")
$image=imagecreatefrompng($newName);
elseif($this->ext=="gif")
$image=imagecreatefromgif($newName);
if($this->ext=="png" or $this->ext=="gif"){ //průhlednost
imagealphablending($image_p, false);
imagesavealpha($image_p,true);
$transparent = imagecolorallocatealpha($image_p, 255, 255, 255, 127);
imagefilledrectangle($image_p, 0, 0, $NewWidth, $NewHeight, $transparent);
}
if(($OrigWidth>$w or $OrigHeight>$h) and $w!=0)
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $NewWidth, $NewHeight, $OrigWidth, $OrigHeight);
else
$image_p=$image; //není třeba zmenšovat
if($vodoznak!=""){ //if watermark is set
//imagealphablending($image_p, false);
//imagesavealpha($image_p,true);
$watermark = imagecreatefrompng($vodoznak);
$ww = imagesx($watermark);
$wh = imagesy($watermark);
if($umisteni{0}=="0") $x=3; else $x=$OrigWidth-$ww-3;
if($umisteni{1}=="0") $y=3; else $y=$OrigHeight-$wh-3;
imagealphablending($watermark, false);
imagesavealpha($watermark,true);
imagecopy($image_p, $watermark, $x, $y, 0, 0, $ww, $wh);
}
if($this->ext=="jpg")
imagejpeg($image_p, $copypath, $komprese);
elseif($this->ext=="png")
imagepng($image_p, $copypath);
elseif($this->ext=="gif")
imagegif($image_p, $copypath);
I don't know, where I shall place alpha settings, please help.
Thank you for every advice!
The imagesavealpha function needs to be applied to the image you're pasting onto the one you created, so to $image instead of $image_p:
imagealphablending($image, true);
imagesavealpha($image,true);
Just like you did with the watermark!

PHP GD transparency doesn't work with iPhone

I am using code to create an image with PHP GD that needs a fully transparent background. When I create it, it displays fine in a browser, but bad in my iPhone app. I don't know why, but in my iPhone it displays all transparency with black. This seems to be a GD problem because when I loaded my GD image into a web editor and reexported it, it displayed fine in my iPhone app. Is there a special way I should export the png image from GD or something or is this some sort of bug? Here is the code:
$filename = "./me.jpg";
$image_s = imagecreatefromjpeg($filename);
list($current_width, $current_height) = getimagesize($filename);
$left = isset($_GET['pl']) ? abs($_GET['pl']) : 0;
$top = isset($_GET['pt']) ? abs($_GET['pt']) : 0;
$width = isset($_GET['cs']) ? abs($_GET['cs']) : 65;
$height = isset($_GET['cs']) ? abs($_GET['cs']) : 65;
$canvas = imagecreatetruecolor($width, $height);
$current_image = imagecreatefromjpeg($filename);
imagecopy($canvas, $current_image, 0, 0, $left, $top, $current_width, $current_height);
$newwidth = 65;
$newheight = 65;
$image = imagecreatetruecolor($newwidth, $newheight);
imagealphablending($image, true);
imagecopyresampled($image, $canvas, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
$mask = imagecreatetruecolor($newwidth, $newheight);
$transparent = imagecolorallocate($mask, 255, 255, 255);
imagecolortransparent($mask, $transparent);
imagefilledellipse($mask, $newwidth / 2, $newheight / 2, $newwidth, $newheight, $transparent);
$red = imagecolorallocate($mask, 0, 0, 0);
imagecopymerge($image, $mask, 0, 0, 0, 0, $newwidth + 10, $newheight + 10, 100);
imagecolortransparent($image, $red);
imagefill($image,0,0, $red);
header('Content-type: image/png');
imagepng($image);
imagedestroy($image);
imagedestroy($mask);
Have you tried using imagesavealpha instead of imagesettransparency? Set alpha blending to false and then use imagesavealpha to true. Finally you'll call the imagecolorallocatealpha function to get your transparent/alpha color instead of imagesettransparency:
imagealphablending($image, false);
imagesavealpha($image, true);
$transparent = imagecolorallocatealpha($image, 255, 255, 255, 127);
imagefilledellipse($mask, $newwidth / 2, $newheight / 2, $newwidth, $newheight, $transparent);
etc...

Categories