How to merge two images and save in php at Run Time? - php

i want to make a picture upload in frame and save both image and frame as a single image ,main thing is whatever the size of image in frame,it should be appear exactly same in a final resulting image after merging.
Here is part of my code:
$imgframe = $_GET['imgframe'];
$imgphoto = $_GET['imgphoto'];
$imgwidth = $_GET['imgwidth'];
$imgheight = $_GET['imgheight'];
$imgleft = substr($_GET['imgleft'],0,-2);
$imgtop = substr($_GET['imgtop'],0, -2);
$src = imagecreatefromjpeg($imgphoto);//'image.jpg'
$dest = imagecreatefrompng($imgframe);//clip_image002.png
imagealphablending($dest, false);
imagesavealpha($dest, true);
imagecopyresampled(
$dest, $src, $imgleft, $imgtop, $imgleft, $imgtop,
$imgwidth, $imgheight, $imgwidth, $imgheight
);

As per your comment below the question, you are using the wrong function.
The PHP manual page for imagecopymerge states that it copies a part of an image onto another. It states that you can specify the origin coordinates, width and height of the region to copy from the source, and the coordinates in the destination in which to place that region.
In other words, it takes a rectangular area of a given size from the source image and puts it on top of the destination, at the given location. It does NOT ask for the size of the region into which you are copying it, only the location. Therefore, it does not resize the copied region, but copies it pixel-for-pixel.
The function you actually need is imagecopyresampled, which allows you to specify the size of the destination region, and will smoothly scale the source region to fit.
EDIT
You are still having a problem because you are using the same coordinates and the same dimensions in the source and the destination parameters. Same dimensions == no resizing.
$imgframe = $_GET['imgframe'];
$imgphoto = $_GET['imgphoto'];
// I am assuming these specify the area of the imgphoto which
// should be placed in the frame?
$imgwidth = $_GET['imgwidth'];
$imgheight = $_GET['imgheight'];
$imgleft = substr($_GET['imgleft'],0,-2);
$imgtop = substr($_GET['imgtop'],0, -2);
// now you also need to get the size of the frame so that
// you can resize the photo correctly:
$frameSize = getimagesize($imgframe);
$src = imagecreatefromjpeg($imgphoto);//'image.jpg'
$dest = imagecreatefrompng($imgframe);//clip_image002.png
imagealphablending($dest, false);
imagesavealpha($dest, true);
imagecopyresampled(
$dest, $src,
0, 0, // these two specify where in the DESTINATION you want to place the source. You might want these to be offset by the width of the frame
$imgleft, $imgtop, // the origin of area of the source you want to copy
$frameSize[0], $frameSize[1], // These specify the size of the area that you want to copy IN TO (i.e., the size in the destination), again you might want to reduce these to take into account the width of the frame
$imgwidth, $imgheight // the size of the area to copy FROM
);

Related

How to crop image with dimensions (without quality loss) in PHP?

I need to crop the image with PHP by using the dimensions.
And save it into the local with JPEG format.
Dimensions that i receive is,
{"left":82.5,"top":48.875,"width":660,"height":371.25}
I need to crop from Original size of the image.
Ex. image is 1200x800, then the result image dimension from the actual size, not resizing or any. Because the quality should be same.
How could i use these params to crop the image ?
Is it possible ?
Use the built-in imagick class:
$image = realpath("/path/to/your/image.extension");
$cropped = realpath("/path/to/your/output/image.png");
$imObj = new Imagick();
$imObj->cropImage($width, $height, $offset_x, $offset_y);
$imObj->setImageFormat("png"); // this is unnesesary, you can force an image format with the extension of the output filename.
$imObj->writeImage($cropped);
As for lossless output, use an image format with lossless encoding. PNG is perfect for the job, since it was designed for network transfer (hence the "Adam-7" interlacing).
Check this related question about lossless image formats on graphic design stack:
What are lossless image formats?
You can use imageCopyResampled function which was designed pretty much exactly for this.
$image = imagecreatefromjpeg($imageFileURL);
/***
* resize values (imported)
***/
$left = 82;
$top = 49;
$width = 660;
$height = 371;
/***
* Create destination image
***/
$newImage = imagecreatetruecolor($width,$height);
$saveToFile = "destintion filespace of image file.jpg"
if(imagecopyresampled($newImage, $image, //dest/source images
0, 0, // dest coordinates
$left, $top, // source coordinates
$width, $height, // size of area to paste to
$width, $height // size of area to copy from
)){
imagejpeg($newImage,$saveToFile,100); //zero compression saved to file
print "image resized ok!!";
}
The new fileimage will be the size specified with $width,$height and will be offset from the original image by the values given in $left and $top. From your question this looks like what you want. This will not resize or change the compression of the image (until you save the file and then possibly set these details yourself).

Adding multiple images on single image (with data from database)

I've tried everything i know for the last 3 days, but can't figure it out, so i hope someone could help me on this one.
I want to get multiple records from a database. In the database is for every single record the link to a thumbnail, x-coordinate and an y-coordinate specified.
The image (a map of a building) must be created starting with an empty map of a building (plattegrond.jpg). Then, multiple thumbnails must be added which contains numbers (see image below) on the coordinated specified in the database. When all the thumbnails are added, it must be saved as something like Project1.jpg or whatever.
$emptymap = "plattegrond.jpg"; // this is a map of a building
$newmap = "Project1.jpg"; // this must be the new map with the images
header('Content-type: image/jpeg');
$im = #imagecreatefromjpeg('maps/'.$emptymap) or die("Cannot Initialize new GD image stream");
$im2 = #imagecreatefromjpeg('thumbnails/'.$linkToThumbnail);
imagecopy($im, $im2, $xcoord, $ycoord, 0, 0, imagesx($im2), imagesy($im2));
imagejpeg($im, 'maps/'.$newmap, 100);
imagedestroy($im);
imagedestroy($im2);
The thumbnails already exists and are all small images saved as 1.jpg, 2.jpg, 3.jpg, etc.
So, in summary:
How do i put multiple images with coordinates, which are specified in a database , on that single image?
All suggestions are welcome!
This is a preview of a map with a single thumbnail:
With the help of Darren his link, i managed to figure it out, finaly! I can sleep again :)
<?php
$coords = array
(
array("2","100","200"),
array("3","200","100"),
array("4","250","30"),
array("5","134","90")
);
$arrlength = count($coords);
$map = "Project2.jpg";
for($x = 0; $x < $arrlength; $x++) {
addThumb($map, $coords[$x][0], $coords[$x][1], $coords[$x][2]);
}
function addThumb($map, $thumb, $xcoord, $ycoord)
{
$thumb .= ".jpg";
$imMap = imagecreatefromjpeg('maps/'.$map);
$imThumb = imagecreatefromjpeg('thumbnails/'.$thumb);
imagecopy($imMap, $imThumb, $xcoord, $ycoord, 0, 0, imagesx($imThumb), imagesy($imThumb));
imagejpeg($imMap, 'maps/'.$map, 100);
imagedestroy($imMap);
imagedestroy($imThumb);
}
?>

Calculate nearest possible dimension value PHP (keeping ratio)

I am trying to implement API for image resizing. It is created not exactly for image processing, this is only one part/feature of API.
What I want to implement.
I have url for retrieving image from server it looks like
mywebpage.com/api/product/42/image
This url will return URL to full image of product with id 42.
Everything is ok.
We can specify desired size with GET parameters like this
mywebpage.com/api/product/42/image?width=200&height=300
It also looks fine
But my question if following.
As we can have different images on server with different dimension and aspect ratio, I need to keep this ratio while resizing.
For example I need image to fit 200x300 container but I have 1024x576 (16:9) image on the server. I need to resize this image but keep initial aspect ratio(16:9) but to fit desired container.
How can I efficiently calculate new image size to return depending on incoming desired dimension and current image aspect ratio.
I want to thank everyone in advance for any help or advises.
Here is a script I used to make similar thing. Quite old , so may be not up to date.
<?php
if( isset($_GET["width"]) && is_numeric($_GET["width"]))
$target_width = intval($_GET["width"]);
else
$target_width= 200;//default value
if( isset($_GET["height"]) && is_numeric($_GET["height"]))
$target_height = intval($_GET["width"]);
else
$target_height= 300;//default value
if( isset($_GET["id"]) && is_numeric($_GET["id"]))//prevent any unwanted filesystem access
$original_image_path = "img/products/$id.jpg";
else
$original_image_path = "placeholder.png"
//http://php.net/manual/fr/function.getimagesize.php
$image_size = getimagesize($original_image_path);
//get the ratio of the original image
$image_ratio= $image_size[1]/ $image_size[0];
$original_image = imagecreatefromjpeg($original_image_path);
$new_image = imagecreatetruecolor($target_width, $image_ratio * $target_width);
//paints the image in white
//http://php.net/manual/en/function.imagefill.php
//http://php.net/manual/en/function.imagecolorallocatealpha.php
imagefill( $new_image, 0, 0, imagecolorallocatealpha($new_image, 255,255,255,127) );
imagesavealpha($new_image, TRUE);
/*
Copies the original to the new, preserving the ratio.
The original image fills all the width of the new,
and is placed on the top of the new.
http://php.net/manual/en/function.imagecopyresized.php
*/
imagecopyresized(
$new_image,$original_image,
0,0,
0,0,
$target_width,$image_ratio * $target_width,
$image_size[0],$image_size[1]
);
//image is returned in response to the request
header ("Content-type: image/png");
imagepng( $new_image );
?>
Well if you need to always fit a container of 200x300 (or what ever is passed through the URL), you may not because able to simply resize it because as you are aware it will affect the images aspect ratio.
If this is the case what you can do is resize the image to the closest size then crop the remainder of the image.
I assume you will be using imagemagick for this. Have you checked out the documentation? The cropThumbnailImage method does what I just explained.
Example usage:
/* Read the image */
$im = new imagick( "test.png" );
/* create the thumbnail */
$im->cropThumbnailImage( 80, 80 );
/* Write to a file */
$im->writeImage( "th_80x80_test.png" );
http://php.net/manual/en/imagick.cropthumbnailimage.php

cropping image propery from a specific portion using GD library

I am not able to crop the image bellow properly using this code. I am not sure about the problem but some of the jpg are cropped correctly with this code.
For coordinate selection i am using Image Cropper in front end.
For the image i have attached bellow, cropping doesn't happen according to starting point x and y, and it starts from different position for some images like the one bellow.
Cropping width and height is ok but starting point is not though i have provided x and y value.
$sourceFile = 'test.jpg';
$destinationFile = 'dest/test.jpg';
$jsonData = '{"x": 142, "y":233, "width":372, "height":209}';
$dataCropValue = json_decode($jsonData);
$src_img = imagecreatefromjpeg($sourceFile);
list($width, $height) = getimagesize($sourceFile);
$dst_img = imagecreatetruecolor($dataCropValue->width, $dataCropValue->height);
imagecopyresampled($dst_img, $src_img, 0, 0 , $dataCropValue->x , $dataCropValue->y ,
$dataCropValue->width, $dataCropValue->height ,
$dataCropValue->width, $dataCropValue->height);
imagejpeg($dst_img, $destinationFile);

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!

Categories