Friends i want to generate one png image from multiple transparent PNG image but the issue is that i can generate only last image
Both images can not combine.
My code is given below
$x = 363;
$y = 267;
$im_dest = imagecreatetruecolor ($x, $y);
imagealphablending($im_dest, false);
$im = imagecreatefrompng('2.png');
$im1 = imagecreatefrompng('1.png');
imagecopy($im_dest, $im1, 0, 0, 0, 0, $x, $y);
imagecopy($im_dest, $im, 0, 0, 0, 0, $x, $y);
imagesavealpha($im_dest, true);
imagepng($im_dest, 'small_redfade.png');
These are the images which i am using to join in single image
http://s11.postimg.org/h6lui7yjn/image.png
http://s21.postimg.org/o7zdnwcnb/image.png
Here is code which works:
$width = 210;
$height = 190;
$layers = array();
$layers[] = imagecreatefrompng("img/01_boy_faceB.png");
$layers[] = imagecreatefrompng("img/01_boy_hairB.png");
$image = imagecreatetruecolor($width, $height);
// to make background transparent
imagealphablending($image, false);
$transparency = imagecolorallocatealpha($image, 0, 0, 0, 127);
imagefill($image, 0, 0, $transparency);
imagesavealpha($image, true);
/* if you want to set background color
$white = imagecolorallocate($image, 255, 255, 255);
imagefill($image, 0, 0, $white);
*/
imagealphablending($image, true);
for ($i = 0; $i < count($layers); $i++) {
imagecopy($image, $layers[$i], 0, 0, 0, 0, $width, $height);
}
imagealphablending($image, false);
imagesavealpha($image, true);
imagepng($image, 'final_img.png');
?>
ImageMagick::Composite can handle this, sadly haven't done in GD so will leave others to explain how to do it there.
Something like:
<?php
$firstImage = new Imagick("firstImage.png");
$secondImage = new Imagick("secondImage.png");
$firstImage->compositeImage($secondImage, Imagick::COMPOSITE_COPYOPACITY, 0, 0 );
header('Content-type: image/png');
echo $firstImage;
?>
This should preserve alpha.
Related
I want to add a color layer over a image in php using gd.
This is the image:
I want to overlay this with this color: #ABD0D2
I made a quick image how it should look at the end.
Keep in mind that the image should still be transparent
So far I have this code:
$img = imagecreatefrompng('image.png');
imagesavealpha($img, true);
imagefill($img, 0, 0, imagecolorallocatealpha($img, 0, 0, 0, 127));
// make overlay with new color???
imagepng($img, 'new.png');
imagedestroy($img);
You can create a new image, filled with your target colour, and then merge the two:
$img = imagecreatefrompng('image.png');
$w = imagesx($img);
$h = imagesy($img);
imagesavealpha($img, true);
$img2 = imagecreatetruecolor($w, $h);
imagefill($img2, 0, 0, imagecolorallocatealpha($img, 0xAB, 0xD0, 0xD2, 64));
imagecopy($img, $img2, 0, 0, 0, 0, $w, $h);
imagepng($img, 'new.png');
imagedestroy($img);
imagedestroy($img2);
Result:
It's not completely clear to me how you want to maintain transparency (as your expected result image isn't transparent) so in the code above I've set the 'mask' colour at 50% opacity.
That worked for me:
$width = 400;
$height = 400;
$image = imagecreatefrompng('img.png');
$blueOverlay = imagecreatetruecolor($width, $height);
imagesavealpha($image, true);
imagealphablending($image, false);
imagesavealpha($blueOverlay, true);
$blue = imagecolorallocatealpha($blueOverlay, 0, 0, 255, ceil(0.22 * 127));
imagefill($blueOverlay, 0, 0, $blue);
imagecopymerge($blueOverlay, $image, 0, 0, 0, 0, $width, $height, 70);
imagepng($blueOverlay, 'imgWithOverlay.png');
imagedestroy($image);
imagedestroy($blueOverlay);
So I'm trying to take two large images (but later I'll be combinging 6 images in total), resize them to the x, y width, height I have taken from photoshop, and combine them into one 460 x 230 sized image.
This is the code I'm using
<?php
$dest = imagecreatefrompng('https://blzgdapipro-a.akamaihd.net/hero/ana/career-portrait.png');
$src = imagecreatefrompng('https://blzgdapipro-a.akamaihd.net/game/rank-icons/season-2/rank-6.png');
imagealphablending($dest, false);
imagesavealpha($dest, true);
imagealphablending($src, false);
imagesavealpha($src, true);
//imagescale($dest, 396, 161.92);
$some = imagecreate(460, 230);
$dest2 = resize($dest, 396, 162);
$src2 = resize($src, 79.19, 79.19);
//imagecopyresized($dest, $dest, 0, 0, 0, 0, 396, 161.92, 1098, 449);
imagecopyresized($src, $src, 10, 10, 0, 0, 79.19, 79.19, 256, 256);
//$img2 = imagecopymerge($dest, $src, 0, 0, 0, 0, 256, 256, 100); //have to play with these numbers for it to work for you, etc.
imagecopymerge($dest2, $src2, 0, 0, 0, 0, 460, 230, 50);
header('Content-Type: image/png');
imagepng($dest, 'merged2.png');
imagepng($dest2);
//file_put_contents('merged.png', $contents);
imagedestroy($dest);
imagedestroy($src);
imagedestroy($some);
imagedestroy($dest2);
imagedestroy($src2);
imagedestroy($img2);
//imagedestroy($then);
function resize($img, $width, $height, $stretch = false)
{
$temp = imagecreatetruecolor($width, $height);
imagealphablending($temp, true);
imagesavealpha($temp, true);
$bg = imagecolorallocatealpha($temp, 0, 0, 0, 0); // Background color
imagefill($temp, 0, 0, $bg);
if ($stretch)
{
imagecopyresampled($temp, img, 0, 0, 0, 0, $width, $height, imagesx($img), imagesy($img));
}
else
{
if (imagesx($img) <= $width && imagesy($img) <= $height)
{
$fwidth = imagesx($img);
$fheight = imagesy($img);
}
else
{
$wscale = $width / imagesx($img);
$hscale = $height / imagesy($img);
$scale = min($wscale, $hscale);
$fwidth = $scale * imagesx($img);
$fheight = $scale * imagesy($img);
}
imagecopyresampled($temp,
$img,
($width - $fwidth) / 2, ($height - $fheight) / 2,
0, 0,
$fwidth, $fheight,
imagesx($img), imagesy($img)
);
}
return $temp;
}
The issue is that the image rendered is very faded
because of this line:
imagecopymerge($dest2, $src2, 0, 0, 0, 0, 460, 230, 50);
If I change the 50, which is the PCT value to 100, it shows one image with a black background (masking the other image), but if I change it to 0, it shows only the other image with a black background (masking the other image)
If the value is either 0 or 100, the image shown is at its full color though. How do I merge these 2 images together while preserving their transparency and vibrancy of color?
Instead of imagecopymerge use imagecopy. You also always need to correctly specify the dimensions of the source image when copying:
$dest = imagecreatefrompng('https://blzgdapipro-a.akamaihd.net/hero/ana/career-portrait.png');
$src = imagecreatefrompng('https://blzgdapipro-a.akamaihd.net/game/rank-icons/season-2/rank-6.png');
$dest2 = resize($dest, 396, 162);
imagedestroy($dest);
$src2 = resize($src, 79, 79); // should be int not float.
imagedestroy($src);
// the last 2 params must match the width/height of the $src2 image.
imagecopy($dest2, $src2, 0, 0, 0, 0, 79, 79);
imagedestroy($src2);
header('Content-Type: image/png');
imagepng($dest2);
imagedestroy($dest2);
You don't need to change the alpha settings on $dest or $src because they aren't being rendered - you render the new image resource created in, and returned by, your resize function. Because of this you do need to slightly change the function:
function resize($img, $width, $height, $stretch = false)
{
$temp = imagecreatetruecolor($width, $height);
imagealphablending($temp, false); // changed to false.
imagesavealpha($temp, true);
...
Edit:
You might be better off simply using the imagescale function instead of using your own resize function:
$dest = imagecreatefrompng('https://blzgdapipro-a.akamaihd.net/hero/ana/career-portrait.png');
$src = imagecreatefrompng('https://blzgdapipro-a.akamaihd.net/game/rank-icons/season-2/rank-6.png');
$dest2 = imagescale($dest, 396);
imagealphablending($dest2, false);
imagesavealpha($dest2, true);
$src2 = imagescale($src, 79);
imagecopy($dest2, $src2, 0, 0, 0, 0, 79, 79);
header('Content-Type: image/png');
imagepng($dest2);
imagedestroy($dest);
imagedestroy($src);
imagedestroy($dest2);
imagedestroy($src2);
I have this script, which makes an image and posts it on another image:
<?php
$img=imagecreatetruecolor(150,20);
imagealphablending($img,false);
$col=imagecolorallocatealpha($img,255,255,255,127);
$black = imagecolorallocate($img, 0, 0, 0);
imagecolortransparent($img, $black);
imagefilledrectangle($img,0,0,180,20,$col);
imagealphablending($img,true);
$font='../ttf/0001.ttf';
$color = imagecolorallocate($img, 0, 0, 0);
imagettftext($img,11,0,5,14,$color,$font,'Text goes here');
imagealphablending($img,false);
imagesavealpha($img,true);
imagejpeg($img, '../custom_images/test.jpg');
// Create image instances
$dest = imagecreatefromjpeg('../custom_images/121536.jpg');
$src = imagecreatefromjpeg('../custom_images/test.jpg');
$width = imagesx($src);
$height = imagesy($src);
imageantialias($src, true);
$color = imagecolorallocatealpha($src, 0, 0, 0, 127);
$rotated = imagerotate($src, 0, $color);
imagesavealpha($rotated, true);
$trans_colour = imagecolorallocatealpha($rotated, 0, 0, 0, 127);
imagefill($rotated, 0, 0, $trans_colour);
imagepng($rotated, 'shahid.png');
$new_img = imagecreatefrompng('shahid.png');
$width = imagesx($new_img);
$height = imagesy($new_img);
// imagecopymerge($dest, $new_img, 50, 50, 0, 0, $width+60, $height+60, 100);
imagecopymerge_alpha($dest, $new_img, 0, 20, 0, 0, $width, $height, 100);
// Output and free from memory
header('Content-Type: image/png');
imagepng($dest);
imagedestroy($dest);
imagedestroy($src);
?>
2 things:
Background is not transparent
I want the Width and Height to be automatic, so if the text is short, the image is it to.
What do I fault?
I have a custom bicycle configurator that layers transparent png files with css.
http://www.gallantbicycles.com/build/no1/
I need to add the ability to combine them into one file dynamically so the user can download an image or share it.
This is where I'm at right now, but it results in a black background and only the front most image is seen in the result:
$width = 720;
$height = 500;
$layers = array();
$layers[] = imagecreatefrompng("pathtomyimage/image.png");
$layers[] = imagecreatefrompng("pathtomyimage/image.png");
$layers[] = imagecreatefrompng("pathtomyimage/image.png");
$image = imagecreatetruecolor($width, $height);
imagealphablending($image, false);
imagesavealpha($image, true);
for ($i = 0; $i < count($layers); $i++) {
imagecopymerge($image, $layers[$i], 0, 0, 0, 0, $width, $height, 100);
}
header('Content-type: image/png');
imagepng($image);
You have to replace this code
imagealphablending($image, false);
imagesavealpha($image, true);
for ($i = 0; $i < count($layers); $i++) {
imagecopymerge($image, $layers[$i], 0, 0, 0, 0, $width, $height, 100);
}
by
imagealphablending($image, true);
for ($i = 0; $i < count($layers); $i++) {
imagecopymerge($image, $layers[$i], 0, 0, 0, 0, $width, $height, 100);
}
imagealphablending($image, false);
imagesavealpha($image, true);
imagealphablending must be true in order to correcly stack the layers, but it must be false to save the image.
Try this solution: Merge two images with transparencies in PHP
use imagecopyresampled instead of imagecopymerge
Here is code which works:
$width = 210;
$height = 190;
$layers = array();
$layers[] = imagecreatefrompng("img/01_boy_faceB.png");
$layers[] = imagecreatefrompng("img/01_boy_hairB.png");
$image = imagecreatetruecolor($width, $height);
// to make background transparent
imagealphablending($image, false);
$transparency = imagecolorallocatealpha($image, 0, 0, 0, 127);
imagefill($image, 0, 0, $transparency);
imagesavealpha($image, true);
/* if you want to set background color
$white = imagecolorallocate($image, 255, 255, 255);
imagefill($image, 0, 0, $white);
*/
imagealphablending($image, true);
for ($i = 0; $i < count($layers); $i++) {
imagecopy($image, $layers[$i], 0, 0, 0, 0, $width, $height);
}
imagealphablending($image, false);
imagesavealpha($image, true);
imagepng($image, 'final_img.png');
?>
All right! I combined all of your answers to come up with a solution that actually works!
Thanks for the help and I hope this helps someone!
$width = $height = null;
$layers = [];
foreach ($imageLayerPaths as $layer) {
if (!is_file($layer)) {
continue;
}
$layers[] = imagecreatefrompng($layer);
if ($width === null) {
$size = getimagesize($layer);
$width = $size[0];
$height = $size[1];
}
}
if (empty($layers)) {
throw new \Exception("No valid image layers to create the image");
}
// Create image base with transparent background
$image = imagecreatetruecolor($width, $height);
imagealphablending($image, false);
$transparency = imagecolorallocatealpha($image, 0, 0, 0, 127);
imagefill($image, 0, 0, $transparency);
imagesavealpha($image, true);
// Add each layer on the image
imagealphablending($image, true);
foreach ($layers as $layer) {
imagecopyresampled($image, $layer, 0, 0, 0, 0, $width, $height, $width, $height);
}
imagealphablending($image, false);
imagesavealpha($image, true);
imagepng($image, "path/where/you/want/to/save/the/image.png");
So I have png image and I rotate it but i get a black background.. or if i do the color code ofr white i get white.. I tried doing this..
$trans = imagecolorallocatealpha(image, 0, 0, 0, 127);
imagerotate($image, $degree, $trans)
i have also tried..
$trans = imagecolorallocatealpha($image, 255, 255, 255, 127);
Can someone help me out?
here is my code.. if i change allocatealpha to 0, 0, 255, 0 then it goes blue. but with 0, 0, 0, 127 its still black.
function rotate($degrees) {
$image = $this->image;
imagealphablending($image, false);
$color = imagecolorallocatealpha($image, 0, 0, 0, 127);
imagefill($this->image, 0, 0, $color);
$rotate = imagerotate($image, $degrees, $color);
imagesavealpha($image, TRUE);
$this->image = $rotate;
}
$destimg = imagecreatefromjpeg("image.png");
$transColor = imagecolorallocatealpha($destimg, 255, 255, 255, 127);
$rotatedImage = imagerotate($destimg, 200, $transColor);
imagesavealpha($rotatedImage, true);
imagepng($rotatedImage,"rotated.png");
As per the correct comment below, this should be:
$destimg = imagecreatefrompng("image.png");
$transColor = imagecolorallocatealpha($destimg, 255, 255, 255, 127);
$rotatedImage = imagerotate($destimg, 200, $transColor);
imagesavealpha($rotatedImage, true);
imagepng($rotatedImage,"rotated.png");
Make sure you set imagesavealpha to TRUE in order to preserve transparency. http://www.php.net/manual/en/function.imagesavealpha.php
imagesavealpha($image, TRUE);
Have you tried this?
imagecolortransparent
Hope i understood your question!
// Turn off transparency blending (temporarily)
imagealphablending($image, false);
// Create a new transparent color for image
$color = imagecolorallocatealpha($image, 0, 0, 0, 127);
// Completely fill the background of the new image with allocated color.
imagefill($image, 0, 0, $color);
// Restore transparency blending
imagesavealpha($image, true);
You can try this: http://www.exorithm.com/algorithm/view/rotate_image_alpha
$info = pathinfo($pathToImage);
$name = str_replace("." . $info['extension'], "", $info['basename']);
$size = getimagesize($pathToImage);
$type = isset($size['type']) ? $size['type'] : $size[2];
// Check support of file type
if (!(imagetypes() & $type)) {
// Server does not support file type
return false;
}
$source = self::imageCreateFrom($pathToImage, trim($info['extension'])) or notfound();
$transColor = imagecolorallocatealpha($source, 255, 255, 255, 127);
// $transparency = imagecolorallocatealpha($source, 0, 0, 0, 127);
$rotate = imagerotate($source, 360 - $rotate_angle, $transColor);
//imagealphablending($rotate, false);
imagesavealpha($rotate, TRUE);
//imagejpeg($rotate,$pathToThumbs.DIRECTORY_SEPARATOR.$info['basename']);
self::createImage($rotate, $pathToThumbs, $info['basename'], trim($info['extension']));
// imagejpeg($rotate);
imagedestroy($source);
imagedestroy($rotate);
This is what I am using, this work great for .png files with transparent backgrounds. High fives!
function rotate($degrees) {
// Switch from default counter-clockwise to clockwise
$degrees = 360 - $degrees;
// Get the image
$source = imagecreatefrompng("images/image.png");
// Rotate the image
$rotated_image = imagerotate($source, $degrees, imageColorAllocateAlpha($source, 0, 0, 0, 127));
// Save the rotated image
imagepng($rotated_image, 'images/rotated_image.png');
}