How to merge images in PHP? - php

I have two images which are loaded from an external URL. I want to place one image on top of another (keeping the size). I actually don't know the sizes of the images as they are from an external URL and are different each time.
So I want a function which can be called like merge($url1,$url2,$final_name). I have googled on this but none worked.
I want this 3.png :
--------------------------------------------------------------------------
|
IMAGE 1 |
|
|
___________________________________________________________________________
|
IMAGE 2 |
|
|
___________________________________________________________________________
$top_file = 'image1.png';
$bottom_file = 'image2.png';
$top = imagecreatefrompng($top_file);
$bottom = imagecreatefrompng($bottom_file);
// get current width/height
list($top_width, $top_height) = getimagesize($top_file);
list($bottom_width, $bottom_height) = getimagesize($bottom_file);
// compute new width/height
$new_width = ($top_width > $bottom_width) ? $top_width : $bottom_width;
$new_height = $top_height + $bottom_height;
// create new image and merge
$new = imagecreate($new_width, $new_height);
imagecopy($new, $top, 0, 0, 0, 0, $top_width, $top_height);
imagecopy($new, $bottom, 0, $top_height+1, 0, 0, $bottom_width, $bottom_height);
// save to file
imagepng($new, 'merged_image.png');
This does the job but the merged image loses its color and becomes nearly black and white like this:

Instead of this:
// create new image and merge
$new = imagecreate($new_width, $new_height);
I used:
// create new image and merge
$new = imagecreatetruecolor($new_width, $new_height);
It worked!
Thanks!

i looked up ur code but i would save the folder in something like that:
$time = date('d-M-Y') . '-TIME-' . date('H-i-s');
$save_finalimage_socialmedia = public_path("storage/image-{$time}.jpeg");
imagejpeg($new, $save_finalimage_socialmedia);
PS: i did it in the jpeg format, so if you want, you can change in ur format (png,jpg,...)
PS: #user4273356 ur code worked for me

Related

Transparent image on transparent image PHP

I'll explain a bit of my situation.
We got an island with cities. These could be:
Owned by my alliance
Owned by an enemy
Owned by nobody (free)
So we got 3 "cities"-images and an island image, looks like this:
Now we want to put these cities images on the island image. For example, we put a city owned by nobody on the island like this:
<?php
// Get image
$im = imagecreatefrompng('island.png');
imagealphablending($im,true);
// Get our "Free-city-position" image
$stamp = imagecreatefrompng('free.png');
$pos_x = 190 - 15; // Position X = 190 - the half of the free.png image = 30 / 2 = 15
$pos_y = 225 - 15;// Position Y = 225 - the half of the free.png image = 30 / 2 = 15
imagealphablending($stamp,true);
imagecopy($im, $stamp, $pos_x, $pos_y, 0, 0, imagesx($stamp), imagesy($stamp));
// Output image
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);
?>
And now there is our problem: The city image is not transparent on the island image! It looks like this:
I thought imagealphablending should do the trick, but unfortunately, it doesn't.
How can we get the transparant city image on the island?
Taken from PHP's comment on GD functions :
If you are trying to copy a transparant image on to another image, you
might assume that you should apply the ImageAlphaBlending function to
the image that has the transparancy, the source image. In reality, you
must apply the ImageAlphaBlending function to the destination image.
Basically it's saying, "make the specified image respect
transparancy".
Try this way:
#!/usr/bin/php -f
<?php
// Read island image and get dimensions
$island=imagecreatefrompng("island.png");
$w_island=imagesx($island);
$h_island=imagesy($island);
// Read city image and get dimensions
$city= imagecreatefrompng("city.png");
$w_city=imagesx($city);
$h_city=imagesy($city);
// Create output image
$result=imagecreatetruecolor($w_island,$h_island);
imagesavealpha($result,true);
$transparent=imagecolorallocatealpha($result, 0, 0, 0, 127);
imagefill($result, 0, 0, $transparent);
// Splat island onto transparent background
imagecopy($result, $island, 0, 0, 0, 0, $w_island, $h_island);
// Splat city ontop
imagecopy($result, $city, 100, 280, 0, 0, $w_city, $h_city);
imagepng($result,"result.png");
?>

GD adding border to image not working

So I have PHP class and I'm trying to add white border with spacing around the uploaded image:
private function __draw_white_border()
{
// get source image and dimensions.
$src = $this->file_data['im'];
$src_w = imagesx($src);
$src_h = imagesy($src);
// create destination image with dimensions increased from $src for borders.
$dest_w = $src_w + 10;
$dest_h = $src_h + 10;
$dest = imagecreatetruecolor($dest_w, $dest_h);
// draw white border (no need for black since new images default to that).
imagerectangle($dest, 1, 1, $dest_w - 2, $dest_h - 2, 0x00ffffff);
imagerectangle($dest, 0, 0, $dest_w - 1, $dest_h - 1, 0x00ffffff);
// copy source image into destination image.
imagecopy($dest, $src, 5, 5, 0, 0, $src_w, $src_h);
}
this function works good when not in the class but with this class its not working. It seems that this function don't save image or something, I dont know.. It should load image from $this->file_data['im'] i think and save to the same destination for further actions. Where is the problem here?
you need to create 2 images and layer the main image on top of the slightly larger second image. This way the larger image will be seen around the edge of the main image making it look like a border.
http://php.net/manual/en/function.imagecopy.php
I use this to layer the images correctly. If the destination image is larger lets say 100x100px. The source image is 80x80px. You will add 10 to the x and y of the source image which will place the source image in the center of the 100x100px image. If the 100x100px image is a plain black image it will generate a clean black border
You are not putting the amended image back anywhere where you can get to it again after this method is run. This code (see last line) puts it back where the original image came from.
private function __draw_white_border()
{
// get source image and dimensions.
$src = $this->file_data['im'];
$src_w = imagesx($src);
$src_h = imagesy($src);
// create destination image with dimensions increased from $src for borders.
$dest_w = $src_w + 10;
$dest_h = $src_h + 10;
$dest = imagecreatetruecolor($dest_w, $dest_h);
// draw white border (no need for black since new images default to that).
imagerectangle($dest, 1, 1, $dest_w - 2, $dest_h - 2, 0x00ffffff);
imagerectangle($dest, 0, 0, $dest_w - 1, $dest_h - 1, 0x00ffffff);
// copy source image into destination image.
imagecopy($dest, $src, 5, 5, 0, 0, $src_w, $src_h);
$this->file_data['im'] = $dest;
}

FPDF align with Image and Cell

I'm trying to do the following layout in an PDF file generated by FPDF in PHP.
--------------------------------------------------
| | Text1 |
| IMAGE | Text2 |
| | Text3 |
--------------------------------------------------
But I couldn't figure out how to do it by now.
This is the code I'm using
public function floatingImage($imgPath, $height) {
list($w, $h) = getimagesize($imgPath);
$ratio = $w / $h;
$imgWidth = $height * $ratio;
$this->Image($imgPath, $this->GetX(), $this->GetY(), 140, 100);
$this->x += $imgWidth;
}
/* Logbuch is our extension from FPDI, but there's nothing changed
* only a custom header, footer and the floatingImage and loadMapImage function are part of it
*/
$pdf = new logbuch();
// Frontpage
$pdf->AddPage();
$mapImage = $pdf->loadMapImage();
$pdf->setJPEGQuality(75);
$x = 15; $y = 21; $w = 100;
$pdf->floatingImage($mapImage, 100, 100);
$pdf->SetFillColor(154,222,229);
$pdf->Cell(0,0,"Test",0,0,'R',true);
$pdf->Ln();
$pdf->Cell(100,0,"Test",0,0,'R',true);
$pdf->Ln();
$pdf->Cell(100,0,"Test",0,0,'R',true);
This is the result I'm generating by now
If I change the width of the last two cells to 100 it will look like this:
This is nearly what I want, the cells just must align to the right side. How can I do this?
I found the answer myself
You can set an X value to the pdf with determines the position on the X axis.
$pdf->Cell(0,0,"Test",0,0,'R',true);
$pdf->Ln();
$pdf->SetX(100); //The next cell will be set 100 units to the right
$pdf->Cell(100,0,"Test",0,0,'R',true);
$pdf->Ln();
Importend to mention is that after every wrote Cell X will be asigned a new value from the Cell() function. So you need to SetX() before creating a new Cell!

Adding one image at the bottom of another in PHP

I'd like to add one image to the bottom of another in php
I've this to load the images:
//load top
$top = #imagecreatefrompng($templateTop);
//load bottom
$bottom = #imagecreatefrompng($templateBottom);
Now I'd like to add them to one picture and display top and bottom together.
What way can I do this?
Thanks!
Use imagecopy:
$top_file = 'image1.png';
$bottom_file = 'image2.png';
$top = imagecreatefrompng($top_file);
$bottom = imagecreatefrompng($bottom_file);
// get current width/height
list($top_width, $top_height) = getimagesize($top_file);
list($bottom_width, $bottom_height) = getimagesize($bottom_file);
// compute new width/height
$new_width = ($top_width > $bottom_width) ? $top_width : $bottom_width;
$new_height = $top_height + $bottom_height;
// create new image and merge
$new = imagecreate($new_width, $new_height);
imagecopy($new, $top, 0, 0, 0, 0, $top_width, $top_height);
imagecopy($new, $bottom, 0, $top_height+1, 0, 0, $bottom_width, $bottom_height);
// save to file
imagepng($new, 'merged_image.png');
To achieve this you would have to
a) Combine the image and store the result in a file
b) generate a suitable tag to point to it.
c) Avoid using that filename again, until that person had left.
If you want to combine two images just once, then use image magic.
If you frequently want to display two images one under the other, do so using suitable html, and let the browser do it.
E.g. Put the images in a
<div><div><img.../></div><div><img .../></div></div>
which you generate with php in the normal way.
(Which is easier than getting tags to appear here :)
$photo_to_paste = "photo_to_paste.png";
$white_image = "white_image.png";
$im = imagecreatefrompng($white_image);
$im2 = imagecreatefrompng($photo_to_paste);
// Place "photo_to_paste.png" on "white_image.png"
imagecopy($im, $im2, 20, 10, 0, 0, imagesx($im2), imagesy($im2));
// Save output image.
imagepng($im, "output.png", 0);

Create a picture with GD containing other images

I would like to create a picture in PHP with GD composed by different other pictures. For example I have 6 pictures (or more) and I would like to create ONE picture who contain these different pictures.
The Difficulty is that my final picture must have a fixed width and height (304x179), so if the different pictures are too big they must be cut. This is an example from IconFinder :
This picture is composed by 6 images, but the 3rd bird (green) is cutted, and the 4, 5 and 6 are cutted in the bottom. This is what I want, can you give me some help to write this code in PHP ?
Thanks
Create your primary image and consider it your "canvas."
From there, use imagecopy() to copy the smaller images into the canvas image.
See this for example:
<?php
header('Content-Type: image/jpg');
$canvas = imagecreatetruecolor(304, 179);
$icon1 = imagecreatefromjpeg('icon.jpg');
$icon2 = imagecreatefromjpeg('icon2.jpg');
// ... add more source images as needed
imagecopy($canvas, $icon1, 275, 102, 0, 0, 100, 100);
imagecopy($canvas, $icon2, 0, 120, 0, 0, 100, 100);
// ... copy additional source images to the canvas as needed
imagejpeg($canvas);
?>
In my example, icon.jpg is a 100x100 image which I am placing in the canvas such that its top left corner is located at 275, 102 in the canvas, which cuts off the right side.
Edit
I adjusted the code to be more similar to what you're doing.
Here a none tested modify spinet from one of my scripts, hope it can be usefull:
header('Content-type: image/png');
$image = array() //Populate this array with the image paths
//Create the Letters Image Objects
foreach($image as $a){
$image['obj'][] = imageCreateFromPNG($a);
}unset($a);
$canvasW = 300;
$canvasH = 300;
//Create Canvas
$photoImage = imagecreatetruecolor($canvasW,$canvasH);
imagesavealpha($photoImage, true);
$trans_color = imagecolorallocatealpha($photoImage, 0, 0, 0, 127);
imagefill($photoImage, 0, 0, $trans_color);
//Merge Images
$Offset_y = 0;
$images_by_row = 3;
$images_rows_height = 100; // height of each image row
$counter = 0;
foreach($image['obj'] as $a){
$counter++;
$width = ceil(imagesx($a));
$height = ceil(imagesy($a));
if(!isset($offset)){ $offset = 1; }
imageComposeAlpha($photoImage, $a, $offset, $Offset_y,$width,$height);
if($offset >= 1){
$offset = $offset + $width;
}
//Check if new row next time
if($counter >= $images_by_row){
if($images_by_row%$counter){
$offset_y += $images_rows_height;
}
}
}unset($a);
imagepng($photoImage);

Categories