Show cropped portion of jpeg in PHP/GD? - php

I have lots of jpeg images that are oversized (height, width), all with different sizes and different aspect ratios.
I'm showing them from a database like this:
<img src="<?php echo $img1; ?>" width="300" height="400">
What I'd like to have is some kind of php function to display a cropped version of the image like this:
cropjpeg('$img1');
For example, if the image is 600 W, 700 H, have php or GD show a cropped version around 300 W, 400 H starting from the top left hand of the image.
Some caveats:
I can't use CSS to do faux cropping. If you download this cropped image, it needs to be just that, the smaller cropped version.
I don't really want to create and save a new image, so I guess I need this to work "on the fly"
I tried imagecreatefromjpeg and imagejpeg, but it seems as though header('Content-Type: image/jpeg'); is not the right answer since there is more on the html page than just this 1 image
There is a lot of traffic on the site, so it has to tread lightly
Here's the best I found so far, but it uses the header('Content-Type: image/jpeg');
<?php
function cropjpeg($img, $x, $y, $width, $height,$grade=5)
{
// Create image instances
$src = imagecreatefromjpeg($img);
$dest = imagecreatetruecolor(400, 300);
// Copy
imagecopy($dest, $src, 0, 0, 20, 13, 400, 300);
// Output and free from memory
header('Content-Type: image/jpeg');
imagejpeg($dest);
imagedestroy($dest);
imagedestroy($src);
}
cropjpeg('images/bikini.jpg');
?>
Any ideas?

You cannot crop an image in the actual html page as it needs to be processed, that's if you don't want to save it on disk.
You can dump the crop script in a single PHP file with headers and call from HTML the script with path eg:
<img src="http://www.example.org/crop.php?i=bikini.jpg&x=13&y=20&w=400&h=300" alt="" />
and in script you can use
<?php
header('Content-Type: image/jpeg');
function cropjpeg($img, $x, $y, $width, $height,$grade=5) {
//......................
imagecopy($dest, $src, 0, 0, $x, $y, $width, $height);
//......................
}
cropjpeg('images/'.$_GET['i'], (int)$_GET['x'], (int)$_GET['y'], (int)$_GET['w'], (int)$_GET['h']);
?>
You should consider the aspect ratio, and search for a better crop script, you don't have to reinvent the wheel.

Use mod_rewrite to send requests for the relevant image file paths to a PHP script, which does the cropping and sends the image data back in response. It looks like a normal image tag on the page, but the images are really being served by your separate script.
The only issue is that you simultaneously don't want to save the cropped files, but have a lot of traffic so want to "tread lightly". You can't have both ways. If you don't want to re-crop the images on every request, you'll need to save the cropped versions so you can re-serve them on future requests.

Here is a page with a very complete tutorial with everything you need to do this using ajax included
crop with jquery and php
[http://www.skillcorp.com.ve][2]
[2]: http://www.skillcorp.com.ve here also more info relational

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).

Image resize before user-side

UPDATE:
now I learned more I looked alot and modified I got this:
function show_image($image, $new_width, $new_height) {
//$this->helper('file'); why need this?
//$image_content = read_file($image); We does not want to use this as output.
list($old_width,$old_height) = getimagesize("$image");
//resize image
$image = imagecreatefromjpeg($image);
$thumbImage = imagecreatetruecolor($new_width, $new_height);
imagecopyresized($thumbImage, $image, 0, 0, 0, 0, $new_width, $new_height, $old_width, $old_height);
imagedestroy($image);
//imagedestroy($thumbImage); do not destroy before display :)
ob_end_clean(); // clean the output buffer ... if turned on.
header('Content-Type: image/jpeg');
imagejpeg($thumbImage); //you does not want to save.. just display
imagedestroy($thumbImage); //but not needed, cause the script exit in next line and free the used memory
exit;
}
when using this function I get a file, but I need to get a URL
I wanna be able to use:
<img src=" ... ">
Since you can't use GD on the server, a good option might be to handle it on the client side.
One idea that comes to mind is loading the image into an html5 canvas, and using that to manipulate the image characteristics before uploading it to the server.
This post talks about how you'd go about uploading image data straight from a canvas and saving it as an image on your server.
How to save a HTML5 Canvas as an image on a server
You also will likely need to take a look at the JavaScript File API to load the image into the canvas on the client side.
It's not necessarily an easy solution, but it might be your best shot without access to GD and stuff.

dynamic image resize using php

I have an image which i am going to be using as a background image and will be pulling some other images from the database that i want to show within this image. So if i am pulling only 1 image, i want the bottom part of the background image to close after the first image, if there are multiple images then i want it close after those images are shown. The problem with not using separate images is that the borders of the images have a design format and i cannot show them separately.
Take a look at this image . The design format of the right and left borders are more complicated than that to just crop them and use them. Any suggestions if there is any dynamic image resizing thing?
Yes there is. Look at the imageXXXX functions; the ones you are particularly interested in are imagecreate, imagecreatetruecolor, imagecreatefrompng, imagecopyresampled, imagecopyresized, and imagepng (assuming you're dealing with PNG images - there's similar load / save functions for jpeg, gif, and a few other formats).
You should try using the GD extension for PHP, especially have a look at imagecopyresized(). This allows you to do some basic image conversion and manipulation very easily.
A basic example that takes two GET parameters, resizes our myImage.jpg image and outputs it as a PNG image:
<?php
// width and height
$w = $_GET['w'];
$h = $_GET['h'];
// load image
$image = imagecreatefromjpeg('myImage.jpg');
// create a new image resource for storing the resized image
$resized = imagecreatetruecolor($w, $h);
// copy the image
imagecopyresized($resized, $image, 0, 0, 0, 0, $w, $h, imagesx($image), imagesy($image));
// output the image as PNG
header('Content-type: image/png');
imagepng($resized);
Have you tried PHPThumb? I used this class often and its pretty clean and lightweight. I used it here.

Php Imageresize Performance

I'm working on an image resize script for php, and had a few questions..
Currently I'm pulling an external URL as the image, and don't really want to store the new image that is going to be re-sized on my server. Here is what I'm trying to do:
Have the script resize the image, than encode it the resized image in base64 on the fly. Now what I'm wondering is, would this be heavy on performance both doing the encode, and serving up the image with base64 rather than just the url? or would it be better to store the image rather than to store the base64 code for it?
Why are you encoding the resized image? Why not just output it directly. You don't need to save it to a file.
Some relevant lines from php function page:
// Content type
header('Content-type: image/jpeg');
// Resize
imagecopyresized($thumb, $source, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
// Output
imagejpeg($thumb);
To include it in the page you would do something like:
<img src="resizer.php?url=[encoded url here]" />

Categories