Come on, come on. It may be a long explanation.
Points to be clarified
When you use a Crop via Javascript/jQuery, you are not cutting the image itself. You are just saving the coordinates, relative to the image that applied the settings using the Crop plugin, to be able to do Crop with another tool. That’s where PHP comes in.
Do I understand what javascript doesn’t do? Then it is also understood that you will not save the cropped image in the input file for later upload.
So what am I gonna do?
You will actually upload the original image by sending the coordinates together with the form submission - we will use the POST method in the example.
How to do Crop
Crop, as said, is like this:
Javascript capturing the coordinates, saving somewhere (in this case the Hidden form inputs). These coordinates are Crop width and height, and Crop x and y position.
The Form sends the information to PHP.
PHP takes the information (the Crop coordinates) and processes the upload image, with this information, to create the cropped image.
*Did you understand that too? So let’s go to the next step
THE CROP
Anyway, we’ve come here. It’s time to get down to business. I’ll pass on the information needed to create our Crop:
Requirements
* Let’s use the library fengyuanchen/cropper
. all the files we’re going to use are in this github folder Copper/dist.
The cropper
above depends on the jQuery
, in our case of use.
Install the php library Gregwar/Image. She is an excellent one.
You can install it via Composer or else clone the repository. In our example, I will use the composer
.
Structure
I’ve set up the following structure for our test.
crop.php
- contains the code that will perform the image Crop.
index.php
- contains the php form that will send the information to crop.php
. We also loaded the Avascripts used in the test.
default.js
- The javascript file that initializes the plugin in the image selected by our input file present in index.php
.
outros arquivos js
- They are the files from the folder cropper/dist
from github, in addition to jQuery, which we will need. So are they: cropper.js
, cropper.css
, jquery.js
.
The code
This is the code of index.php:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Cropper</title>
<link rel="stylesheet" href="cropper.css">
<script src="jquery.js"></script>
<script src="cropper.js"></script>
<script src="default.js"></script>
<style>
.container {
max-width: 960px;
}
img {
max-width: 100%;
}
</style>
</head>
<body>
<div class="container">
<h1 class="page-header">Cropper with full crop box</h1>
<div id="image-container">
</div>
<form method="post" action="crop.php" enctype="multipart/form-data">
<input type="hidden" name="y" id="y" />
<input type="hidden" name="x" id="x" />
<input type="hidden" name="w" id="w" />
<input type="hidden" name="h" id="h" />
<input type="file" name="image" id="image-file" />
<button type="submit">Salvar</button>
</form>
</div>
<!-- Scripts -->
</body>
</html>
This is the code o crop.php
, which is where the action
form will make the submission of data.
After the upload is successfully completed, I display the cropped image.
In this file we have included the autoload of the Composer, to be able to use the class Gregwar\Image\Image
.
include __DIR__ . '/vendor/autoload.php';
use Gregwar\Image\Image;
if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_FILES['image']['tmp_name'])) {
$tmp_name = $_FILES['image']['tmp_name'];
$y = $_POST['y'];
$x = $_POST['x'];
$w = $_POST['w'];
$h = $_POST['h'];
$filename = sprintf('%s/croped/%s.jpg', __DIR__, uniqid());
Image::open($tmp_name)
->crop($x, $y, $w, $h)
->save($filename, 'jpg');
echo 'Imagem cropada com sucesso';
printf('<img src="croped/%s" />', basename($filename));
}
This is the file responsible for initializing and processing the data from cropper
. Is the file default.js
.
$(function(){
var $imageContainer = $('#image-container');
$('#image-file').change(function () {
var src = window.URL.createObjectURL(this.files[0]);
var $image = $('<img/>');
$image.attr({src: src}).load(function () {
$imageContainer.html($image);
$image.cropper({
aspectRatio: 16 / 9,
crop: function (e) {
$('#x').val(e.x);
$('#y').val(e.y);
$('#w').val(e.width);
$('#h').val(e.height);
}
});
})
});
});
Explanation
Use of Cropper.js
We start first with the plugin cropper
. We have in it the function crop
, that is responsible for returning the data (such as position and size of Crop) each time the user "drag" or "resize" Crop, as image coordinates.
I have 4 Hidden inputs in index.php
. These inputs I named x
, y
, w
and h
.
Where: X
is the position relative to the left (the famous left
css), and Y
, a in relation to height (the position top
of the image).
W
is the simplification of width
, which means width. And h
is height
, that is the time.
The use of Gregwar
This is my favorite part, because it’s object-oriented PHP saving my life.
Here we call the class Image
namespace Gregwar\Image
:
use Gregwar\Image\Image;
The method Image::open
is responsible for opening the image. In this case, I preferred not to save the upload image and then edit it with Crop. I opened the temporary upload file directly.
Image::open($tmp_name)
The method Image::crop
is responsible for cutting the image at the coordinates we want. Remember I said javascript only sends the coordinates? So it’s time to get these coordinates, which will be available in the variable $_POST
.
$y = $_POST['y'];
$x = $_POST['x'];
$w = $_POST['w'];
$h = $_POST['h'];
Note the order the arguments are passed, it is important not to confuse, so Crop does not go wrong.
Image::open($tmp_name)
->crop($x, $y, $w, $h)
And finally, we save the image. With the function uniqid
I named it randomly. I chose the extension to be jpg
. The save directory is croped
.
So the generated name is this:
$filename = sprintf('%s/croped/%s.jpg', __DIR__, uniqid());
The way out will be something like this:
c:\windows\php\crop\croped\24af43676.jpg
So we finally invoke the method save
. In this method, the first argument you have to pass the file name. The second is the format you will save the image. I used jpg
.
The second argument is very useful. It is a way for you to upload any image, but all will be converted to the extension you want.
Image::open($tmp_name)
->crop($x, $y, $w, $h)
->save($filename, 'jpg');
Github with the example
Just clone the following repository to perform the tests:
https://github.com/wallacemaxters/exemplo-php-crop
Note: No need to use Poser, if you clone my example of github.
Enjoy!
Updating
I was alerted by the user @Bacco to reformulate my statement that javascript does not do Crop.
In fact, most of the plugins, which I worked on to make an image Rop, the medium they used to make Crop was exactly as previously said: Crop was not done, but only uploaded the image along with the coordinates.
However, @Bacco reminded me that it is possible to make a Crop of a certain image and send the cut made for a canvas
. After that, we capture the canvas image and send it to the server. Generally we use Base64 to perform this operation.
The important point of adding this last detail to the answer is that by doing so (which @Bacco said) you can decrease the use of server bandwidth, since you will not upload the entire image and then cut it by php. You will be sending the Base64 of the already cropped image, to then just save it.
Good question, useful and I believe it will help many people who have the same problem. + 1 e fav para acompanhar
– Tiago P.C
Upload by php with Crop I never did, but I’ve already done with resize, if there is no drive I publish a reply
– Guilherme Lopes
http://www.keenthemes.com/preview/metronic/theme/admin_3_material_design/form_image_crop.html
– Diego Souza
It should not be pending. I could answer.
– Lollipop
Hi Zoom, this plugin seems to be very good, but I could not find where I insert the image via input file, which is what I need.
– Ricardo Afonso
I’m thinking about answering the question. In a Crop operation, you need the plugin (which will only generate the image coordinates, it will not cut anything from it "for real"). From there, you send this information to php and process it with GD images. My explanation would be a bit complex. You’re ready?
– Wallace Maxters
@Lollipop question reopened
– Math
Hello Wallace, I understand what you said. I believe this is the best way. I am prepared :)
– Ricardo Afonso
@Ricardoafonso ok. Already added the answer :D
– Wallace Maxters
Thanks Wallace, I’ll read it and try to understand. Then put it right :D
– Ricardo Afonso
Hello Wallace, I had a little trouble here, but I got it. It worked perfectly. Thank you very much!
– Ricardo Afonso