In many cases, users upload images that need to be cropped, such as Avatar or something. But before the implementation of such requirements are very complex, often need to upload the image to the server, and then return to the user, let the user determine the clipping coordinates, sent to the server, the server cut back to return to the user, back and forth need 5 steps. The steps are tedious to say, when many users upload pictures, it also affects server performance.
The advent of HTML5 allows us to make this requirement more convenient. Although the technology described here seems a bit outdated (the front end of the "outdated", you know), but still a little reference value. Here I only say the main points, the concrete realization of the students to study slowly.
Below, I wrote a demo, in the input box to choose their own server URL, create a good picture and click Submit Upload, and then go to the server to see the effect bar ~ ~
The browser requires support for the following Feature:
- File API
- Blob
- Atob
- Canvas
Code directly from the existing project to transplant, did not go through the "too much" test, write very messy, no comments, we slowly look at it ... Focus on the JS script 28 lines, the clipImage
function, students can jump to see directly.
http://jsfiddle.net/windwhinny/d5qan0q7/ Click to preview
First step: Get the file
HTML5 supports input[type=file]
obtaining file information directly from an element or reading the contents of a file. We can use the following code to achieve:
$ (' input[type=file] '). Change (function() { var file=this. Files[0]; // continue...});
Part II: Read the file and generate
Image
Elements
This step needs to be used FileReader
, and this class is designed to read local files. Plain text or binary can be read, but the local file must be user-allowed to read, that is, the user to input[type=file]
select the file in, you can read it.
By the FileReader
way we can convert the image file into a DataURL
URL that starts with, it data:image/png;base64,
can then be placed directly image.src
, so that the local image is displayed.
$ (' input[type=file] '). Change (function(){ varfile= This. files[0]; varReader=NewFileReader (); Reader.onload=function(){ //Reader.result to access the generated Dataurl varUrl=Reader.result; Setimageurl (URL); }; Reader.readasdataurl (file);});varImage=NewImage ();functionsetimageurl (URL) {image.src=URL;}
Image
is the html
label inside
, so it can be inserted directly into the document stream.
Step three: Get crop coordinates
This step is nothing to say, the implementation of a lot of methods, you need to get the following four crop box coordinates:
- Y-coordinate
- X-coordinate
- Height
- Width
Fourth: Crop the picture
This is the time we need to use canvas
, canvas
and the same as the picture, so when new to canvas
determine its high-width. Here we also apply the image.naturalHeight
image.naturalWidth
two properties to get the original size of the picture.
You need to call when you put the picture canvas
drawImage
in, this interface parameter is more, there is a detailed description on the MDN.
DrawImage (image, SX, SY, swidth, sheight, dx, dy, dwidth, dheight)
Because we use canvas
just to crop the picture, so we need to create a new one canvas
so that its size and the size of the picture after the image is equal, at this time canvas
quite with our crop box. This function can also be used to scale large graphs into small pictures, students study it.
// The following four parameters are obtained from step three var x, y, width, height; var canvas=$ (' <canvas width= ' ' +width+ ' "height=" ' +height+ ' "></canvas> ') [0], CTX =canvas.getcontext (' 2d '); Ctx.drawimage (Image,x,y,width,height,0,0, Width,height); $ ( document.body). Append (canvas);
After you canvas
join the document flow, you'll see the cropped effect. But we also need to upload images to the server.
Fifth step: Read the cropped picture and upload it
At this point we want to get the canvas
information in the picture, toDataURL
it can be converted to use the above DataURL
. The base64 information is then extracted and window.atob
converted into a binary string. However window.atob
, the converted result is still a string, and the direct Blob
or error. So we're going to use a Uint8Array
conversion. Anyway, it's kind of troublesome.
var data=canvas.todataurl (); // Dataurl is in the format "data:image/png;base64,****", and the comma is preceded by some descriptive text, we just need the comma after the line data= Data.split (', ') [1 =window.atob (data); var ia = new Uint8array (data.length); for (var i = 0; i < data.length; I++) {Ia[i] = Data.charcodeat (i);}; // var blob=new Blob ([ia], {type: "image/ PNG "});
This time the cropped file is stored in blob
, we can think of it as a normal file, added to FormData
, and uploaded to the server.
FormData
As the name implies, it is used to create the form data, with append
a key value in the form of the data can be added. But his biggest feature is the ability to manually add files or Blob
types of data, and the Blob
data will be treated as files. Native JS can be passed directly to xhr.send(fd)
, jquery can be placed data
in the request.
var fd=New FormData (); Fd.append (' file ', blob); $.ajax ({ URL:" Your.server.com ", Type:" POST ", data:fd, success:function( ){}});
Then you should be able to receive this file on the server ~
HTML5 locally crop the picture and upload it to the server (GO)