Search code examples
phpphp-gd

How to merge jpg and png images using php?


This is png image:

enter image description here

This is jpg image:

enter image description here

Both are same width and height.

Expected output:

enter image description here

Code that I am using:

<?php
header('content-type: image/jpeg');
if(isset($_GET['source'])){
$source = $_GET['source'] ;
$watermark = imagecreatefrompng('png.png');
$watermark_height = imagesy($watermark);
$watermark_width = imagesx($watermark);

$image = imagecreatetruecolor($watermark_width,$watermark_height);
$image = imagecreatefromjpeg($source);

imagecopymerge($image, $watermark, 0, 0, 0, 0, $watermark_width, $watermark_height, 100  );
imagepng($image);

}
?>

Current output:

enter image description here

Could you help me to get my expected output?


Solution

  • You have to enable the alpha channel. To use the merge function and to keep the alpha channel, you can use the function published here: https://www.php.net/manual/en/function.imagecopymerge.php#92787

    Your code will look like this:

    header('content-type: image/png');
    
       function imagecopymerge_alpha($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct){
            // creating a cut resource
            $cut = imagecreatetruecolor($src_w, $src_h);
    
            // copying relevant section from background to the cut resource
            imagecopy($cut, $dst_im, 0, 0, $dst_x, $dst_y, $src_w, $src_h);
           
            // copying relevant section from watermark to the cut resource
            imagecopy($cut, $src_im, 0, 0, $src_x, $src_y, $src_w, $src_h);
           
            // insert cut resource to destination image
            imagecopymerge($dst_im, $cut, $dst_x, $dst_y, 0, 0, $src_w, $src_h, $pct);
        }
    
        
    $source ='b.jpg';
    $watermark = imagecreatefrompng('a.png');
    $watermark_height = imagesy($watermark);
    $watermark_width = imagesx($watermark);
    
    $image = imagecreatetruecolor($watermark_width,$watermark_height);
    $image = imagecreatefromjpeg($source);
    
    imagecopymerge_alpha($image, $watermark, 0, 0, 0, 0, $watermark_width, $watermark_height, 100  );
    imagepng($image);
    

    Otherwise the alpha channel is filled with a color and your background gets completely filled.

    Be careful: You also mix up content-type image/jpeg and the output function imagepng. (I've chosen image/png & imagepng in my solution.)