Laravel imagecopy lowers image quality - php

I am coding a Laravel project where I let users add their own small image to a bigger image (something like milliondollarhomepage.com).
I use the PHP imagecopy(); to add the small image to the bigger image. The problem is: the colors get really poor after merging the two images together. I think the new image only has the colors of the previous image, so no new colors can be added to the image.
My code:
$pixel = GET_INFO_HERE;
$dest = imagecreatefrompng(public_path('storage/pixels.png'));//get big image
$src = imagecreatefrompng(public_path('storage/uploads/' . $pixel->imagename));//get small image to add
imagecopy($dest, $src, $pixel->x_position, $pixel->y_position, 0, 0, $pixel->width, $pixel->height);
ob_start();
imagepng($dest);
$newpixelsimg = ob_get_clean();
Storage::put('public/pixels.png', $newpixelsimg);//save new image
imagedestroy($dest);
imagedestroy($src);
I tried to use imagetruecolortopalette($dest, false, 255); before the imagecopy(); method, but it didn't change anything.
I have been searching for solutions for a long time now, but I couldn't get it to work yet.
Is there anyone who has a solution for this?

Related

Uploading and Merging images in PHP

So I'm looking to create an internal tool where our employees can upload a picture of themselves, which automatically merges it with a white border at the bottom (company logo border) and their name on top of it. This way the offices can easily print the pictures for employee boards
So what I need is:
- merge border, picture and text into one image.
- Upload function with crop tool.
What I found is:
- PHP Image Magician (http://phpimagemagician.jarrodoberto.com/)
This basically has all functions I need available so naturally I got excited but I ran across one thing:
In the 14.1_upload.php file it refers to the following:
require_once('image_lib/upload_class.php');
the image_lib/upload_cass.php file doesnt come with the download from the website.
Is there something I'm missing or would you guys recommend not to use PHP Image Magician at all?
I'm looking to make it a very basic and simple tool but functional.
Thanks a bunch in advance
Uploading Image is a very easy process, you can use W3School reference to understand it well http://www.w3schools.com/php/php_file_upload.asp
About Image merge you can use below code:
<?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);
?>

How to put a watermark text across the whole image in diagonal position?

I have connected my Google Drive with my website and im getting images in this format: https://googledrive.com/host/{$GoogleID}. What i want to do is to add a text (not image) watermark to all the images im getting from Google Drive. I already tried with:
http://php.net/manual/en/image.examples.merged-watermark.php
http://phpimageworkshop.com/tutorial/1/adding-watermark.html
Both of them dosent work for me or i cant get them to work i dont know why. I will give an example for an image url: https://googledrive.com/host/0B9eVkF94eohMRlBQVENRWE5mc2c
I have also tried the code from this answer, but it dosent work as well. I guess the problem should be that the files i'm getting from Google Drive are not with the file extention and maybe this cause the problem. This is only my guess...
UPDATE:
i managed to show the photo on the website, but how to put the text in diagonal possition across all the photo like this
try to read image with file_get_contents or fopen and create image from string.
$im = imagecreatefromstring(file_get_contents("image url"));
and then use this example: http://php.net/manual/en/image.examples.merged-watermark.php
Thanks to #Durim Jusaj for helping me out with this one and finally i got the answer after a lot of searching and dealing with a lot of problems i will share my knowledge with u guys. So i will post the code and i will explain what is the code doing.
First thing first. Include this function in your file. This function is finding the center of the image. I havent wrote it i found it in the php docs under the comments so maybe it can be done without it or this function can be modified to be better written.
function imagettftext_cr(&$im, $size, $angle, $x, $y, $color, $fontfile, $text)
{
// retrieve boundingbox
$bbox = imagettfbbox($size, $angle, $fontfile, $text);
// calculate deviation
$dx = ($bbox[2]-$bbox[0])/2.0 - ($bbox[2]-$bbox[4])/2.0; // deviation left-right
$dy = ($bbox[3]-$bbox[1])/2.0 + ($bbox[7]-$bbox[1])/2.0; // deviation top-bottom
// new pivotpoint
$px = $x-$dx;
$py = $y-$dy;
return imagettftext($im, $size, $angle, $px, $py, $color, $fontfile, $text);
}
Load the image you want to apply the watermark to. I'm using Google Drive to extract my photos so thats why im using the file_get_contents, if you are the case like mine then use this, BUT otherwise use what is common and if your picture have extension like .jpg or .png you can use imagecreatefromjpeg or imagecreatefrompng. So it should be something like that $im = imagecreatefromjpeg('photo.jpeg'); for example.
$im = imagecreatefromstring(file_get_contents("https://drive.google.com/uc?id=" . $v['GoogleID']));
After that we need to calculate the position of watermark so we want the watermark to be in the center and to auto adjust its size based on the size of the photo. So on the first like we store all the attributes of the image to array. Second and third lines we calculate where is the center of the image (for me dividing it by 2.2 worked great, you can change this if u want to adjust the position. Last line is the size of the watermark according to the size of the image. This is very important as the watermark will be small or very big if u have images with different sizes.
list($width, $height, $type, $attr) = getimagesize("https://drive.google.com/uc?id=" . $v['GoogleID']);
$width = $width / 2.2;
$height = $height / 2.2;
$size = ($width + $height) / 4;
Set the content-type
header('Content-Type: image/png');
Create the image. I dont know why it should be done twice, but im following the php manual.
$im = imagecreatefromstring(file_get_contents("https://drive.google.com/uc?id=" . $v['GoogleID']));
Create some colors. So, if you want your watermark to be transparent (like mine) you have to use imagecolorallocatealpha, otherwise use imagecolorallocate. Last parameter is the transparency. You can google every function name for more info from the php doc.
$black = imagecolorallocatealpha($im, 0, 0, 0, 100);
The text to draw. Simple as that. Write what you want your text to be.
$text = 'nima.bg';
Replace path by your own font path. Put a font in your server so the code can take it (if you dont have already).
$font = 'fonts/ParsekCyrillic.ttf';
Adding all together. Basically you are creating the final image with the water mark with this function. The magic ;)
imagettftext_cr($im, $size, 20, $width, $height, $black, $font, $text);
Now this is the tricky part! If you want to just display the image without saving it to your server you can simply copy and paste this code, but the website will load very slow if you have more then 2-3 images. So, what i suggest you to do it to save the final images to your server and then display it. I know you will have duplicates, but this is the best choice i think.
ob_start();
imagepng($im);
$image = ob_get_contents();
ob_end_clean();
imagedestroy($im);
echo "<img src='data:image/png;base64," . base64_encode($image) . "'>";
}
OR you can save the images to your server and then display them which is much much faster. The best thing you can do is to process all the images create them with the watermark and then display them (so you have them ready to be show when a visitor visit your website).
imagepng($im, 'photo_stamp.png');
imagedestroy($im);
And the final result for me was that.
UPDATE: As of 2017 you can extract the image using this link 'https://drive.google.com/uc?id=(GoogleID)' or you can just use the 'webContentLink' property of the Google_DriveFile Object (it will give you the same link).

Building an image from Tiles

I'm working on a website and I'm trying to use images, the only problem being the person who made the original site converted all the images into tiles and I have no idea how to work with them so I'm trying to convert it back into full-sized images which I can use.
I made some code that loops through the folder and selects all the images in a column and adds them to an array which is then stored in a array for rows and then I use this bit of code:
$image = imagecreate(1525, 2023);
foreach($tiles as $row => $columns) {
foreach($columns as $col => $filename) {
list($w, $h) = getimagesize($filename);
$tile = imagecreatefromjpeg($filename);
imagecopy($image, $tile, $row * $w, $col * $h, 0, 0, $w, $h);
}
}
header('content-type: image/jpeg');
imagejpeg($image);
so that I can build the image and then see what it's built (I don't want to save it until it properly builds the image.) but for some reason when I build it using this it seems to take the colour and detail out and the tiles don't fit into the original background image I create which I know is the right size because the dimensions are stored in a xml file which I read from and then when i loop to create the arrays I use the width and height given by the xml file as a check to make sure the tiles fit in the size, which they do. I've also built the image in fireworks and it looks like it should but when I build it using my script it takes out the detail and colour..
if you need the looping code for whatever reason let me know and I'll edit this to include it. but I've creating the arrays myself using the filenames stored and it still has the same errors.
if anyone can help I'd be grateful.
I managed to solve the issue by using
$imgdest = imagecreatetruecolor($width, $height);
imagealphablending($imgdest, false);
imagesavealpha($imgdest, true);
Instead of:
$image = imagecreate(1525, 2023);
And I was also using the wrong tile size somehow it worked when I got the tile size out of the xml file though.
In case anyone comes across a similar problem.

php Imagick rotate and merge

i have 2 images one background and another one is layer first i want to rotate it then i want to place it somewhere using x and y.. it can be done using GD but in gd when rotate the image i get low quality and zigzag border.. so i tried to rotate in imagick it done its job good without zigzag and without loosing quality.. so i want to know how to place that rotated image to background...
Background
Image_2
Output should look like this
EDIT:
The code I have tried so far:
<?php
$imagick = new Imagick();
$imagick->readImage('137.png');
$imagick->rotateImage(new ImagickPixel('none'), -13.55);
$imagick->writeImage('my_rotated.png');
$imagick->clear();
$imagick->destroy();
?>
I was trying to find a solution myself. I guess this should get what you need:
$background = 'background.png';
$image = new Imagick($background);
// you can place the code below in a loop to put more images in order
$imgfile = 'foreground-image.png';
$part1 = new Imagick($imgfile);
$part1->rotateImage(new ImagickPixel('none'), -13.55);
$image->compositeImage($part1, Imagick::COMPOSITE_OVER, $left, $top);
$image->writeImage('my_rotated.png');
//save , flush , destroy etc...

add canvas if height < X

Sorry my lousy english, I'm sleepy and struggling with this about 3 days ago.
I'm using "slideViewerPro 1.5" to display an image gallery (PHP + JS).
However, this js script forces me to have all the images at the same size.
So, when I have a vertical picture, I would like to add some white canvas to it so it won't get distorted.
I've tried offline, using Irfanview. Won't work.
I've tried hacking up some GD and PHP scripts. Won't work either.
Messing around the slideViewerPro javascript source... neither.
Also... I've read this about 20 times, and still can't figure out if GD is a proper solution.
http://www.rubblewebs.co.uk/imagemagick/GDexamples.php
Can someone enlight me please?!
I hope this helps with using GD:
$im=imagecreatefrompng($filename);
$width=imagesx($im);
$height=imagesy($im);
$newwidth = 550;
$newheight = 325;
$output = imagecreatetruecolor($newwidth, $newheight);
imagecopymerge($output, $im, ($width<550?550-$width:0), ($height<325?325-$height:0), 0, 0, $width, $height,0);
imagepng($output);
imagedestroy($output);
imagedestroy($im);
$filename is the filename, and then we create a blank image of size 550x325 and paste the image onto the new canvas

Categories