PNG composition using GD and PHP - php

I am trying to take a rectangular png and add depth using GD by duplicating the background and moving it down 1 pixel and right 1 pixel. I am trying to preserve a transparent background as well.
I am having a bunch of trouble with preserving the transparency.
Any help would be greatly appreciated.
Thanks!
$obj = imagecreatefrompng('rectangle.png');
$depth = 5;
$obj_width = imagesx($obj);
$obj_height = imagesy($obj);
imagesavealpha($obj, true);
for($i=1;$i<=$depth;$i++){
$layer = imagecreatefrompng('rectangle.png');
imagealphablending( $layer, false );
imagesavealpha($layer, true);
$new_obj = imagecreatetruecolor($obj_width+$i,$obj_height+$i);
$new_obj_width = imagesx($new_obj);
$new_obj_height = imagesy($new_obj);
imagealphablending( $new_obj, false );
imagesavealpha($new_obj, true);
$trans_color = imagecolorallocatealpha($new_obj, 0, 0, 0, 127);
imagefill($new_obj, 0, 0, $trans_color);
imagecopyresampled($new_obj, $layer, $i, $i, 0, 0, $obj_width, $obj_height, $obj_width, $obj_height);
//imagesavealpha($new_obj, true);
//imagesavealpha($obj, true);
}
header ("Content-type: image/png");
imagepng($new_obj);
imagedestroy($new_obj);

The solution to virtually any related problem with PHP GD is using this small utility:
http://phpimageworkshop.com/
It´s a PHP Class based on GD... but it´s has two "insignificant" differences:
Extremely easy
Always get the work done
Two days ago I have a similar problem (Join multiple PNG Images into a single one PNG using PHP) but this Library saves the day!

Related

Merging image causing black artefact in background

Very new to php and im trying to merge two images together using GD.
I have tried doing this, however it is causing the merged image to have a weird black background.
Anyone know where i am going wrong?
<?php
$image_1 = imagecreatefrompng('image.png');
$overlay = imagecreatefrompng('image2.png');
$size = getimagesize('image2.png');
imagecopy($image_1, $overlay, 0, 0, 0, 0, $size[0], $size[1]);
imagepng($image_1, "mergedImage.png");
?>
<img src="image.png"/>
<img src="image2.png"/>
<img src="mergedImage.png">
This is the output i get.
source images:
Telling GD to retain alpha channel information immediately after creating your target image should fix the issue:
<?php
$image_1 = imagecreatefrompng('image.png');
imagesavealpha($image_1, true);
$overlay = ...
At the moment you end up with a duplicate of image2.png, but I assume you want to achieve a different result:

Converting JPEG/PNGs to PNG for database storage but can't keep background transparency/colour when displaying, in PHP

I've a script I use to convert JPEGs or PNGs to PNGs for database storage, I encode the file into base64 and store it in a database, I pull the file from the database or cache and when displaying it on a website I just pull the image data from the database or cache and do a base64 decode on it and display it using a standard IMG tag.
The issue I'm having is, no matter if the background is transparent or what colour I create as the image's background it always shows up as black when being displayed on the webpage.
I've tried numerous of the questions on the right side and none of the answers seems to work for me.
Encode Function
public function encode($image, $resize = false, $dirLevel = '')
{
$vTempFileName = TEMP_DIR . '_'.rand(1111111, 9999999) . '.png';
// Convert image to PNG
$image = imagecreatefromstring(file_get_contents($image));
imagealphablending($image, true);
imagepng($image, $vTempFileName);
$vImageDetails = array(base64_encode(file_get_contents($vTempFileName)), filesize($vTempFileName));
// Remove temporary file after processing
#unlink($vTempFileName);
return $vImageDetails;
}
Decode Function
echo base64_decode($image);
I've also tried using the below two functions
To save transparency you need to add imagesavealpha See http://php.net/manual/en/function.imagesavealpha.php
public function encode($image, $resize = false, $dirLevel = '')
{
$vTempFileName = TEMP_DIR . '_'.rand(1111111, 9999999) . '.png';
// Convert image to PNG
$image = imagecreatefromstring(file_get_contents($image));
imagealphablending($image, true);
imagesavealpha($image, true);
imagepng($image, $vTempFileName);
$vImageDetails = array(base64_encode(file_get_contents($vTempFileName)), filesize($vTempFileName));
// Remove temporary file after processing
#unlink($vTempFileName);
return $vImageDetails;
}
imagefill will perform a flood fill on the selected coordinates with the desired color defined as $transparent See: http://php.net/manual/en/function.imagefill.php
$fillColor = imagecolorallocatealpha($image, 0, 0, 0, 127);
imagefill($image, 0, 0, $fillColor);
To flood fill the adjoining color at the top left of the image with the desired fillColor.
Otherwise to add transparency use imagecolortransparent see http://php.net/manual/en/function.imagecolortransparent.php
$replaceBlack = imagecolorallocate($image, 0, 0, 0);
imagecolortransparent($image, $replaceBlack);
to replace the color black as transparent.
This may or may not help you but... you really don't want to store images into a database if you can avoid it. Is there a good reason you are doing this? File systems are good at storing binary files. Databases are good at storing data. Use the appropriate tool for the job – store it as a file.

How to merge multiple images together using GD library?

I have removed my original question as I have managed to partially get this working, what I have is 7 images,
https://dl.dropboxusercontent.com/u/58586640/layer1.png
https://dl.dropboxusercontent.com/u/58586640/layer2.png
https://dl.dropboxusercontent.com/u/58586640/layer3.png
https://dl.dropboxusercontent.com/u/58586640/layer4.png
https://dl.dropboxusercontent.com/u/58586640/layer5.png
https://dl.dropboxusercontent.com/u/58586640/layer6.png
https://dl.dropboxusercontent.com/u/58586640/layer7.png
Each of these images when placed over the top of each other should create one image that slots together perfectly.
The current result i have is,
https://dl.dropboxusercontent.com/u/58586640/Screen%20Shot%202013-12-11%20at%2018.31.57.png
As you can see it works nearly perfectly but 2 of the layers are either not being copied or are not getting the alphas saved correctly. I am not sure what I am doing wrong, as all the other layers seem to working fine, the images that are coming in as black are,
https://dl.dropboxusercontent.com/u/58586640/layer3.png https://dl.dropboxusercontent.com/u/58586640/layer4.png
Here is my current code,
<?php
$images = array('img/layer1.png', 'img/layer2.png', 'img/layer3.png', 'img/layer4.png', 'img/layer5.png', 'img/layer6.png', 'img/layer7.png');
// foreach($images as $i) {
// var_dump(file_exists($i));
// }
// Allocate new image
$img = imagecreatetruecolor(704, 469);
// 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, 704, 469);
// Free memory
imagedestroy($cur);
}
header('Content-Type: image/png');
imagepng($img);
As you can see I have checked to make sure that the files exist, and they do so it must be GD problem, anyone have ideas?
Funny I did exactly this yesterday here's how I did it using a static background layer and a QR code which is generated prior to the combine.
$template = imagecreatefrompng("./images/asset_barcode_template.png");
//QR created fine assemble final image
$qrimage = imagecreatefrompng($this->qrfilename);
//final image assembled just fine
imagecopy($template, $qrimage, 230, 6, 0, 0, 106, 106);
imagepng($template,$filename,0,PNG_NO_FILTER);

PHP set the attribute for an image with matrix values

as the topic,I need to set the attribute for an image or create an image with the attribute what I get from a client as the matrix values.
I found a function named imageconvolution,but it doesn't work out.Maybe I used it incorrectly.
here is the code:
<?php
$image = imagecreatefromgif('http://www.php.net/images/php.gif');
$emboss = array(array(0, 0, 100), array(0, 0, 200), array(0, 0, 1));
imageconvolution($image, $emboss, 1, 0);
header('Content-Type: image/png');
imagepng($image, null, null);
?>
the matrix values are used to scale or rotate or move the image.Is these code right?
I hope to find out someone to teach me.
Thanks a lot.
Scaling, rotation and moving are affine transforms. You cannot use convolution for this matrixes.
I think the easiest way to use the php Imagick extension. It has an affineTransformImage function which you can use: http://php.net/manual/en/imagick.affinetransformimage.php

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