How to Merge 3 Images into 1 Image via PHP

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

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.

How to merge multiple images and text into single image?

And i achieved it this way,

Used these 3 images, img1.png,img2.png,img3.png

Sample ImageSample ImageSample Image

And create-image.php file

 <?php
createimageinstantly();
//$targetFolder = '/gw/media/uploads/processed/';
//$targetPath = $_SERVER['DOCUMENT_ROOT'] . $targetFolder;
//$img3 = $targetPath.'img3.png';
//print_r(getimagesize('http://www.vapor-rage.com/wp-content/uploads/2014/05/sample.jpg'));
function createimageinstantly($img1='',$img2='',$img3=''){
$x=$y=600;
header('Content-Type: image/png');
$targetFolder = '/gw/media/uploads/processed/';
$targetPath = $_SERVER['DOCUMENT_ROOT'] . $targetFolder;

$img1 = $targetPath.'img1.png';
$img2 = $targetPath.'img2.png';
$img3 = $targetPath.'img3.png';

$outputImage = imagecreatetruecolor(600, 600);

// set background to white
$white = imagecolorallocate($outputImage, 255, 255, 255);
imagefill($outputImage, 0, 0, $white);

$first = imagecreatefrompng($img1);
$second = imagecreatefrompng($img2);
$third = imagecreatefrompng($img3);

//imagecopyresized ( resource $dst_image , resource $src_image , int $dst_x , int $dst_y , int $src_x , int $src_y , int $dst_w , int $dst_h , int $src_w , int $src_h )
imagecopyresized($outputImage,$first,0,0,0,0, $x, $y,$x,$y);
imagecopyresized($outputImage,$second,0,0,0,0, $x, $y,$x,$y);
imagecopyresized($outputImage,$third,200,200,0,0, 100, 100, 204, 148);

// Add the text
//imagettftext ( resource $image , float $size , float $angle , int $x , int $y , int $color , string $fontfile , string $text )
//$white = imagecolorallocate($im, 255, 255, 255);
$text = 'School Name Here';
$font = 'OldeEnglish.ttf';
imagettftext($outputImage, 32, 0, 150, 150, $white, $font, $text);

$filename =$targetPath .round(microtime(true)).'.png';
imagepng($outputImage, $filename);

imagedestroy($outputImage);
}
?>

And the result image is
Sample Image

Reference : imagecopyresized & imagettftext

thank you for the suggestions made via comments/answers.
And also i blogged this in detail http://sumankc.com/2016/01/30/merge-multiple-images-and-text-to-create-single-image-php-gd-library/
Good day !!

Merge multiple pictures into one

There is a function named imagecopy. This function overrides a part of the destination image using a source image. The given part is specified as parameters. Before you tell me that this does not solve your problem, I have to add that the pixels in the destination picture will not be overriden by the pixels of the source picture if the pixels are transparent. You need to use imagealphablending and imagesavealpha on the source picture, like this:

public static function experimental($images, $width, $height, $dest = null) {

$index = 0;

if ($dest === null) {
$dest = $images[$index++];
}

while ($index < count($images)) {
imagealphablending($images[$index], true);
imagesavealpha($images[$index], true );
imagecopy($dest, $images[$index++], 0, 0, 0, 0, $width, $height);
}

return $dest;
}

If we have these two pictures:

Sample Image
Sample Image

The result will be this:

Sample Image

how to merge multiple image in single image

Use a counting variable $i which you can reset once you hit the 25th image.
Also, you forgot to clear the mapImage before drawing the next sheet.

$mapImage = imagecreatetruecolor(5366, 3378);
$bgColor = imagecolorallocate($mapImage, 255, 255, 255);
imagefill($mapImage, 0, 0, $bgColor);
$temp=1;
$i = 0;
foreach ($srcImagePaths as $index => $srcImagePath)
{
$x = ($i % 5) * (1073 + 1) + 1;
$y = floor($i / 5) * (672 + 1) + 1;
$tileImg = imagecreatefromjpeg($srcImagePath);
imagecopy($mapImage, $tileImg, $x, $y, 0, 0, 1073, 672);
imagedestroy($tileImg);
$i++;

if($i>=25 || $index==count($srcImagePaths)-1)
{
imagejpeg($mapImage,dirname($_REQUEST['csvsheet'])."/finalcard/sheet".$temp.".jpg");
$temp++;
$i = 0;
imagefilledrectangle($mapImage, 0, 0, 5366, 3378, $bgColor);
}
}

combine 16 images into 1 big image with php

Step 1: get an array with source image locations
This step is different for anybody, but in its easiest form you would define something like this:

$srcImagePaths = Array('https://diceattack.files.wordpress.com/2011/01/tile_e_o_fh.png',
'https://diceattack.files.wordpress.com/2011/01/tile_e_g_fh.png',
'https://diceattack.files.wordpress.com/2011/01/tile_e_b_fh.png',
'https://diceattack.files.wordpress.com/2011/01/tile_b_q_fh.png');

Step 2: define some measures and initialize a blank ‘background’ image
Here we use the first GD functions: imagecreatetruecolor() creates a generic ‘base’ image, imagecolorallocate() to define an RGB color and imagefill() to fill our generic image with that color.

$tileWidth = $tileHeight = 28;
$numberOfTiles = 12;
$pxBetweenTiles = 1;

$mapWidth = $mapHeight = ($tileWidth + $pxBetweenTiles) * $numberOfTiles;

$mapImage = imagecreatetruecolor($mapWidth, $mapHeight);
$bgColor = imagecolorallocate($mapImage, 50, 40, 0);
imagefill($mapImage, 0, 0, $bgColor);

Step 3:

think at which coordinates you want your source images to end up
There are some different ways to specify this, but if you are dealing with many images of the same size it makes sense to write a small function that maps an (array) index to a set of X,Y coordinates. Here is mine which arranges them all in a 12×12 square grid:

function indexToCoords($index)
{
global $tileWidth, $pxBetweenTiles, $leftOffSet, $topOffSet, $numberOfTiles;

$x = ($index % $numberOfTiles) * ($tileWidth + $pxBetweenTiles) + $leftOffSet;
$y = floor($index / $numberOfTiles) * ($tileWidth + $pxBetweenTiles) + $topOffSet;
return Array($x, $y);
}

Step 4: loop over the source images and copy them on the base image
We use function imagecopy() to do this, like this:

/*
* COPY SOURCE IMAGES TO MAP
*/

foreach ($srcImagePaths as $index => $srcImagePath)
{
list ($x, $y) = indexToCoords($index);
$tileImg = imagecreatefrompng($srcImagePath);

imagecopy($mapImage, $tileImg, $x, $y, 0, 0, $tileWidth, $tileHeight);
imagedestroy($tileImg);
}

Note how we used the indexToCoords() function in there – we do not want all the >source images on the same position of course.

Step 5 (intermezzo): resizing an image with PHP
The same imagecopy() function we used to put our source images on the base image can also be used to resize images. Handy if you want to generate thumbnails automatically! Here’s how you can do that:

/*
* RESCALE TO THUMB FORMAT
*/

$thumbSize = 200;
$thumbImage = imagecreatetruecolor($thumbSize, $thumbSize);
imagecopyresampled($thumbImage, $mapImage, 0, 0, 0, 0, $thumbSize, $thumbSize, $mapWidth, $mapWidth);

Final step: set header to tell the browser there’s an image coming, and output the final image

/*
* OUTPUT THUMBNAIL IMAGE
*/

header ("Content-type: image/png");
imagepng($thumbImage); //change argument to $mapImage to output the original size image

And that’s it! Note that you may not want a uniformly filled background but rather a real background image – you can easily do this by using imagecreatefrompng() in step 2.

Here’s all the code once more together for convenience.

<?php

//Source image paths (DISCLAIMER: this is just to demonstrate, to generate a real TT map you need 144 of these)
<pre>$srcImagePaths = Array('https://diceattack.files.wordpress.com/2011/01/tile_e_o_fh.png',
'https://diceattack.files.wordpress.com/2011/01/tile_e_g_fh.png',
'https://diceattack.files.wordpress.com/2011/01/tile_e_b_fh.png',
'https://diceattack.files.wordpress.com/2011/01/tile_b_q_fh.png');
</pre>
/*
* INIT BASE IMAGE FILLED WITH BACKGROUND COLOR
*/

$tileWidth = $tileHeight = 28;
$numberOfTiles = 12;
$pxBetweenTiles = 1;
$leftOffSet = $topOffSet = 1;

$mapWidth = $mapHeight = ($tileWidth + $pxBetweenTiles) * $numberOfTiles;

$mapImage = imagecreatetruecolor($mapWidth, $mapHeight);
$bgColor = imagecolorallocate($mapImage, 50, 40, 0);
imagefill($mapImage, 0, 0, $bgColor);

/*
* PUT SRC IMAGES ON BASE IMAGE
*/

function indexToCoords($index)
{
global $tileWidth, $pxBetweenTiles, $leftOffSet, $topOffSet, $numberOfTiles;

$x = ($index % 12) * ($tileWidth + $pxBetweenTiles) + $leftOffSet;
$y = floor($index / 12) * ($tileWidth + $pxBetweenTiles) + $topOffSet;
return Array($x, $y);
}

foreach ($srcImagePaths as $index => $srcImagePath)
{
list ($x, $y) = indexToCoords($index);
$tileImg = imagecreatefrompng($srcImagePath);

imagecopy($mapImage, $tileImg, $x, $y, 0, 0, $tileWidth, $tileHeight);
imagedestroy($tileImg);
}

/*
* RESCALE TO THUMB FORMAT
*/
$thumbSize = 200;
$thumbImage = imagecreatetruecolor($thumbSize, $thumbSize);
imagecopyresampled($thumbImage, $mapImage, 0, 0, 0, 0, $thumbSize, $thumbSize, $mapWidth, $mapWidth);

header ("Content-type: image/png");
imagepng($thumbImage);

?>

Source

It will definitely work . Used my self several times :)

Joining Multiple Images into one with a PHP script

So here what i ended up with

<?php
header('Content-type: image/png');

function imageComposeAlpha( &$src, &$ovr, $ovr_x, $ovr_y, $ovr_w = false, $ovr_h = false, $opc = 127){
imagecopy($src, $ovr, $ovr_x, $ovr_y, 0, 0, imagesx($ovr), imagesy($ovr) );
}

////////////////////////---////////-----------------------------------

$url = "../../images/socom_font/normal/Socom";

//Covert the String iinto an Array
$letter = str_split(strtoupper ($_GET['name']));
//Populate Letters Image Path
foreach($letter as $a){
//exeptions
if($a == "?"){ $a = "Question"; }
if($a == "/"){ $a = "Slash"; }
if($a == "%"){ $a = "Percent"; }
if($a == " "){ $a = "Space"; }
$image[] = $url.$a.".png";
}unset($a);
//Create the Letters Image Objects
foreach($image as $a){
$image['obj'][] = imageCreateFromPNG($a);
}unset($a);
//calculate Canvas Width
foreach($image['obj'] as $a){
if(!isset($canvasW)){ $canvasW = 0; }
$canvasW = imagesx($a) + $canvasW;
}unset($a);
//Create Canvas
$photoImage = imagecreatetruecolor($canvasW,100);
imagesavealpha($photoImage, true);
$trans_color = imagecolorallocatealpha($photoImage, 0, 0, 0, 127);
imagefill($photoImage, 0, 0, $trans_color);

//Merge Images
foreach($image['obj'] as $a){
$width = ceil(imagesx($a));
if(!isset($offset)){ $offset = 1; }

imageComposeAlpha($photoImage, $a, $offset, 0,$width,100);

if($offset >= 1){
$offset = $offset + $width;
}
}unset($a);
// Save it
//Imagepng($photoImage, 'done.png');
// Output to browser
Imagepng($photoImage);

//Destroy all Image Objects
foreach($image['obj'] as $a){
ImageDestroy($a);
}
ImageDestroy($photoImage);
?>

The Live Link http://thechozenfew.net/projects/font/ImageMerge.php?name=it%20works

Merging two images with PHP

I got it working from one I made.

<?php
$dest = imagecreatefrompng('vinyl.png');
$src = imagecreatefromjpeg('cover2.jpg');

imagealphablending($dest, false);
imagesavealpha($dest, true);

imagecopymerge($dest, $src, 10, 9, 0, 0, 181, 180, 100); //have to play with these numbers for it to work for you, etc.

header('Content-Type: image/png');
imagepng($dest);

imagedestroy($dest);
imagedestroy($src);
?>

Merging multiple images next to each other in PHP

Put imagepng outside of loop:

<?php
header('Content-Type: image/png');

$numbers = array(1, 2, 3, 4, 5, 8, 9);

shuffle($numbers);
$newid=array_slice($numbers,0,6);

$count = 0;
$dest=imagecreatetruecolor(35*6,75);
foreach($newid as $imageSrc) {

$image = imagecreatefrompng("numbers/" . $imageSrc . ".png");
imagecopymerge($dest, $image, (35*$count), 0, 0, 0, imagesx($image), imagesy($image), 100);
$count++;
}
imagepng($dest);

?>

How to merge multiple images with size and position of specificity into a single image with text inscription (API)

As said in the comments by Gaurav Gupta, I suggest you to use Intervention Image PHP package which encapsulate all the GD methods into something easy to use (You can use Imagick also).

You could do something like this :

public function upload(Request $request)
{
$x=$y=600;
$imageMerge = new ImageMerge();
header('Content-Type: image/png');
$validation = $request->validate([
'title' => 'string',
'image' => 'required|file|image|mimes:jpeg,png,gif,webp|max:2048'
]);
$file = $request->file('image')->getClientOriginalName();
$extension = $request->file('image')->getClientOriginalExtension();
$hash = Str::random(10);
$filename = 'mm-image-' . $hash . '.' . $extension;
$path = $file->storeAs('/uploads/images', $filename, ['disk' => 'public']);
$image = storage_path('app/uploads/images/mm-image-1552822080.png');
$c = storage_path('app/uploads/images/mm-image-1552936505.png');
$im3 = file_get_contents($request->title);

$logo = Image::make($file);
$background = Image::make($image);
$person = Image::make($c);

// Resize the picture to insert to the good size
$logo->resize(200, 320);
$person->resize(300, 200);

// Insert those pictures in the background to a specific position with some padding
$background->insert($person, 'left', 30, 0);
$background->insert($logo, 'right', 30, 0);

// Draw white filled rectangle for the text
$background->rectangle(0, 0, 0, 0, function ($draw) {
$draw->background('#FFFFFF');
});

// use callback to define details
$background->text($im3, 0, 0, function($font) {
$font->file(storage_path('app/public/tahoma.ttf'));
$font->size(24);
$font->color('#000000');
$font->align('center');
});

// Resize image to specific output size
$background->resize($x, $y);

$exportName = 'file-'.$hash.'.'.$extension;
Storage::disk('public')->put('/uploads/final/'.$exportName, $background);

$imageMerge->image = $exportName;
$imageMerge->save();
}

This is not a finished script. You still need to calculate all the exact position of elements and verify all the storage paths to be sure every file is imported correctly but in the end Intervention Image is really easy to use.

Here's the methods we used in the documentation so that you can tweak them to your needs :

  • Intervention Installation in Laravel
  • Intervention Make method
  • Intervention Insert method
  • Intervention Rectangle
  • Intervention Text method
  • Intervention Resize method


Related Topics



Leave a reply



Submit