Placing a Transparent PNG onto another Transparent PNG (Bottom Image not showing) - php

I have two images. I am putting imageA over imageB. However this is causing the bottom image (imageB) colors to not show. Instead the transparent part of imageA is overriding imageB.
$dest = imagecreatefrompng(6.png'); (96x96)
$src = imagecreatefrompng(5.png');
imagealphablending($dest, true);
imagesavealpha($dest, true);
imagealphablending($src, true);
imagesavealpha($src, true);
imagecopy($dest, $src, 10, 30, 0, 0, 40, 40);
ob_start();
imagepng($dest);
$imgswap = ob_get_clean();
imagedestroy($dest);
https://i.imgur.com/S3lSQDl.png //img here (I don't have enough reputation to direct link)
As you can see the transparent (white pixels in this example for clarity) are going over marios face. Any ideas?

From docs (https://www.php.net/manual/en/function.imagecolortransparent.php): "Transparency is copied only with imagecopymerge() and true color images, not with imagecopy() or pallete images."
Try: https://www.php.net/manual/en/function.imagecopymerge.php even though it says in the comments it doesn't support aplha.

Related

Crop and Resize image from X and Y Position

I'm trying to crop then resize an image on PHP v5.4, I've read these resources
Put PNG over a JPG in PHP
http://php.net/manual/en/function.imagecopy.php
http://php.net/manual/en/function.imagecopyresampled.php
http://php.net/manual/en/function.call-user-func-array.phPP
PHP watermarking
http://php.net/manual/en/function.imagecreatetruecolor.php
My code is based off the answer from Cropping image in PHP (the dimensions between these images vary alot).
I want to resize this image from 1151x768 to 200x82 and crop the background section at x: 0, y: 686
I'd prefer not bloating the question with the entire 600 lines in this question, $output refers to setwidth1200nzpioneerthursday08398 image
<?php
$output = imagecreatefromjpeg("setwidth1200nzpioneerthursday08398.jpg");
$source_crop_image = imagecreatetruecolor(200, 82);
if(!is_resource($source_crop_image)) {
return $source_crop_image;
}
imagealphablending($output, true);
$source_copy_result = imagecopy($output, $source_crop_image, 0, 0, 0, 686, 200, 82);
$source_copy_result = (bool) $source_copy_result;
if(!$source_copy_result) {
return false;
}
$source_image_result = imagejpeg($source_crop_image, "images/mynewimage.jpg");
$source_image_result = (bool) $source_image_result;
?>
My Image setwidth1200nzpioneerthursday08398
Ideally I'm trying to get it crop the RED SECTION, while keeping the scale intact then resizing to 200x82
My Result
My Expected Result (I created this image using GIMP).
I have no idea why my resulting image is a black box ..
You have imagecopy() arguments in wrong order.
The right one is $source_copy_result = imagecopy($source_crop_image, $output, 0, 0, 0, 686, 200, 82);

How to make a transparent image in PHP

I want to remove a background from my image:
My script can be found here:
<?php
//header('Content-type:jpeg');
// Create image instances
$dest = imagecreatefromjpeg('images/bg.jpg');
$src = imagecreatefrompng('images/Title.png');
imagealphablending($src, false);
imagesavealpha($src, true);
// Copy and merge
imagecopymerge($dest, $src, 0, 300, 0, 0, 700, 150, 75);
// Output and free from memory
imagejpeg($dest,'images/print/imagecopymerge.jpg');
imagedestroy($dest);
imagedestroy($src);
?>
<img src="images/print/imagecopymerge.jpg">
Can anyone help me accomplish this?
It might be easier to make a png image and use that with transparency (Could use Paint.net free :) or Photoshop/Illustrator Paid :(. This will give you more time to work on other things that might you might be finding hard to work out.

Merging two PNG images with the smaller image behind with GD

I am attempting to merge two png images by placing a smaller png behind an image with a "hole" in the center with transparency.
The "Front" image is $src in this example
The "Back" image is $dest in the example
So far, i've gotten it to work in reverse (by putting the $dest image / smaller image in front) using the following code:
imagecopymerge($src, $dest, 300, 150, 0, 0, 150, 150, 100);
However, i'm not sure how to do it with the smaller image "Behind" the bigger image so that it fits perfectly in the hole.
Do I need to recreate the image ($dest) as a larger image (500 x 500) to "paste" the $src image over top of with 0 offset? This stuff is confusing :S
Figured it out.
First I merged the smaller image onto a blank image below that matched the larger image.
Then, I merged the image with the hole onto the new image created above. See as follows:
// Get size of larger image
$sz = getimagesize("larger.jpg");
// Create resources
$backing = imagecreatetruecolor($sz[0],$sz[1]);
$img1 = imagecreatefrompng("larger.jpg");
$img2 = imagecreatefrompng("smaller.jpg");
// Merge backing
imagecopymerge($backing, $img2, 300, 150, 0, 0, 150, 150, 100);
// Merge main
imagecopymerge($backing,$img1, 0, 0, 0, 0, $sz[0], $sz[1], 100);
// Save new image
imagepng($backing,$save);
// Destroy resources
imagedestroy($backing);
imagedestroy($img1);
imagedestroy($img2);
Hope this helps someone!

Transforming transparent `gif` to grayscale while saving transparency

First, I resize the image while saving transparency:
/*
all the classic routine etcetera:
$canvas = imagecreatefrom[png|gif|jpeg]();
$resize = imagecreatetruecolor();
*/
if($blending){
$transparentIndex = imagecolortransparent($canvas);
if($transparentIndex >= 0){
#GIF
imagepalettecopy($canvas, $resize);
imagefill($resize, 0, 0, $transparentIndex);
imagecolortransparent($resize, $transparentIndex);
imagetruecolortopalette($resize, true, 256);
}else{
#PNG
imagealphablending($resize, false);
imagesavealpha($resize, true);
$transparent = imagecolorallocatealpha($resize, 255, 255, 255, 127);
imagefill($resize, 0, 0, $transparent);
}
}
imagecopyresampled($resize, $canvas, 0, 0, 0, 0, $nx, $ny, $x, $y);
// image[png|gif|jpeg]... (image gets saved)
Then, I want to apply grayscale filter to that previously saved image (within a new function):
/*
classic routine again:
$canvas = imagecreatefrom[png|gif|jpeg]()
*/
if($blending){
imagealphablending($canvas, false);
imagesavealpha($canvas, true);
}
imagefilter($canvas, IMG_FILTER_GRAYSCALE);
/*
This fully filters PNG's to Grayscale while saving transparency,
but for GIF, black background is added to my grayscaled picture,
plus, the picture isn't fully grayscale (more like gets high-contrasted with acidic colors).
*/
// image[png|gif|jpeg]
What would be the fix, to preserve transparency when applying IMG_FILTER_GRAYSCALE to gif?
What would be the fix, in order to transform gif to grayscale while saving the transparency? (Question revised due to answer provided by #Pierre)
Thanks in advance!
imagefilter used with the gray scale filter does take care of the alpha channel.
However, gif does not support alpha. So you won't be able to store it using the GIF format.
It is also important to note that the background color (one single color or color index being used as background) has nothing to do with the alpha (level of transparency of a given color or pixel). That means you are responsible to set the background color to the desired single color.
Update
It is not directly possible as the color used as transparent will be modified. That could be considered as a bug as the transparent color may or should be ignored by the filter. But that's another topic.
A workaround could be:
$logo = imagecreatefromgif('php.gif');
$newimg = imagecreatetruecolor(imagesx($logo), imagesy($logo));
/* copy ignore the transparent color
* so that we can use black (0,0,0) as transparent, which is what
* the image is filled with when created.
*/
$transparent = imagecolorallocate($newimg, 0,0,0);
imagecolortransparent($newimg, $transparent);
imagecopy($newimg, $logo, 0,0, 0, 0,imagesx($logo), imagesx($logo));
imagefilter($newimg, IMG_FILTER_GRAYSCALE);
imagegif($newimg, 'a.gif');
this code simply fetch the value of the existing transparent color, convert it to gray and set it back to the color index. This code will only work for palette image like gif but that's the idea.

How can I merge 3 images into 1 image via PHP?

I really cannot find a way to successfully do it.. I've searched google for this and it either has black shades around the images or all the images don't overlap. Could you please help?
I am alright at PHP; I'd give myself a 2/5.. I would really appreciate if someone would be willing to help me out.
I'm looking for a simple api that goes something like:
$color=$_GET['color'];
$face=$_GET['face'];
$hat=$_GET['hat'];
echo '<img src="avatar.php?color=$color&face=$face&hat=$hat">';
Thanks for any help in advance. I can understand php from my knowledge of other languages, too, so don't be afraid to talk technical with me; but not too technical.
there are so many comments on this answer so I'm posting this as an answer.
Got it working on my pc.
use svens code :
$images = array( $_GET['color'], $_GET['face'], $_GET['hat'] );
// Allocate new image
$img = imagecreatetruecolor(58, 75);
// Make alpha channels work
imagealphablending($img, true);
imagesavealpha($img, true);
foreach($images as $fn) {
// Load image
$cur = imagecreatefrompng($fn);
imagealphablending($cur, true);
imagesavealpha($cur, true);
// Copy over image
imagecopy($img, $cur, 0, 0, 0, 0, 58, 75);
// Free memory
imagedestroy($cur);
}
header('Content-Type: image/png'); // Comment out this line to see PHP errors
imagepng($img);
?>
I renamed your images like this so its easier :
smile : a.png
headset : b.png
blue : c.png
Turns out the problem is with the layering it. Putting one behind the other
after you rename the images, use this url -- it will work(works on my pc).
YOUR_FILE.php?hat=b.png&color=c.png&face=a.png
This will still give you a black background. I am not sure if you have the exact same code as above in your file on the server - because I played around with the image order on your link and it does not help. Try copy-pasting this exact same code on a different file and then trying. Play around with the order and check the results.
Here's some code to get you started. However you should note that image processing with gd and alpha channels is voodoo.
<?php
$images = array( $_GET['color'], $_GET['face'], $_GET['hat'] );
// Allocate new image
$img = imagecreatetruecolor(58, 75);
// Make alpha channels work
imagealphablending($img, true);
imagesavealpha($img, true);
foreach($images as $fn) {
// Load image
$cur = imagecreatefrompng($fn);
imagealphablending($cur, true);
imagesavealpha($cur, true);
// Copy over image
imagecopy($img, $cur, 0, 0, 0, 0, 58, 75);
// Free memory
imagedestroy($cur);
}
header('Content-Type: image/png'); // Comment out this line to see PHP errors
imagepng($img);
?>
What you still have to do now is checking the return values (look up the image* functions in the manual) to make sure it doesn't fail silently.
I can't really promise it's going to work with the alpha channels.. If not you'll probably have to go through the comments to the imagecopymerge() or imagecopy() on php.net and see if I missed something.

Categories