HTML5 local image Cropping
Below is a demo I wrote myself. The code is rarely written and many details are not processed. If you have any questions, please kindly advise. Thank you for the ^_^ feature. Step 1: Get the file, read the file, and generate url 2: Use canvas to draw Image 3 based on the container size: use canvas to draw the mask layer. 4. Use canvas to draw the cropped image. 5. Drag the cropping box and crop the image again. PS: This article was written after the demo was written, therefore, the code for multipart pasting is copied directly from the segment in the Code. Pay attention to this object. Step 1: Get the file, read the file, and generate the url: here, I use the file api in html5 to process local file uploads, because it does not need to upload images to the server, and then the server returns the image address for preview. For details, see: use FileReader of File API to upload files
Document. getElementById ('Post _ file '). onchange = function () {var fileList = this. files [0]; var oFReader = new FileReader (); oFReader. readAsDataURL (fileList); oFReader. onload = function (oFREvent) {// called when the read operation is completed successfully. postFile.paintImage(oFREvent.tar get. result); // pass the url of the preview image to the function };}
Step 2: Use canvas to draw images based on the container size: The FileReader using File API in the previous step has obtained the address to upload the image. Next, use canvas to draw the image. Why isn't I just inserting img and re-drawing it with canvas? Actually not. If you use img to insert a page directly, the image cannot be automatically centered. If you use canvas to draw an image, the image can be automatically centered and scaled proportionally, and the coordinates of the image can be easily adjusted, the size is passed to the subsequent mask layer, so that the mask layer can be drawn based on the coordinates of the image and the size of the image. Pay attention to the drawImage method of canvas. Reference here: https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/drawImage
PaintImage: function (url) {var t = this; var createCanvas = t. getImage. getContext ("2d"); var img = new Image (); img. src = url; img. onload = function () {// proportional scaling image (if the image width and height are smaller than the container, the image width and height are equal to the width and height of the original image .) // If the image width or height is greater than that of the container, the width or height is equal to the width or height of the container, and the other height or width is proportional. // t. imgWidth: the width of the image after painting; t. imgHeight: the height of the image after painting; t. px: X axis of the image after painting; t. py: if (img. width <t. regional. offsetWidth & img. height <t. regional. offsetHeight) {t. imgWidth = img. width; t. imgHeight = img. height;} else {var pWidth = img. width/(img. height/t. regional. offsetHeight); var pHeight = img. height/(img. width/t. regional. offsetWidth); t. im GWidth = img. width> img. height? T. regional. offsetWidth: pWidth; t. imgHeight = img. height> img. width? T. regional. offsetHeight: pHeight;} // coordinate t of the image. px = (t. regional. offsetWidth-t. imgWidth)/2 + 'px '; t. py = (t. regional. offsetHeight-t. imgHeight)/2 + 'px '; t. getImage. height = t. imgHeight; t. getImage. width = t. imgWidth; t. getImage. style. left = t. px; t. getImage. style. top = t. py; createCanvas. drawImage (img, 0, 0, t. imgWidth, t. imgHeight); // you can use a canvas to draw an image without directly inserting a background image to adjust the size of the image t in the required frame. imgUrl = t. getImage. toDataURL (); // store the image address t drawn by the canvas. cutImage (); t. drag ();};},
The effect is as follows: Step 3: Use canvas to draw the mask layer. The background image to be cropped has been drawn in the previous step, now we need to draw a mask layer covering the background based on the coordinates and sizes of the background image, and use the clearRect method of the canvas to clear a cropping area to compare it with the area without cropping. (Here, the mask layer is only used to display the effect, and does not crop the image. I wonder if this step can be removed directly? Tell me if you have any children's shoes .)
// Draw the mask layer: t. editBox. height = t. imgHeight; t. editBox. width = t. imgWidth; t. editBox. style. display = 'block'; t. editBox. style. left = t. px; t. editBox. style. top = t. py; var cover = t. editBox. getContext ("2d"); cover. fillStyle = "rgba (0, 0, 0, 0.5)"; cover. fillRect (0, 0, t. imgWidth, t. imgHeight); cover. clearRect (t. sx, t. sy, t. sHeight, t. sWidth );
Step 4: Use canvas to draw the cropped image. in step 3, the mask layer is drawn, but the mask layer is not capable of cropping, it is only used to display the comparison between the cropping area and the non-cropping area, so the image cropping function is started here. The drawImage method of the canvas is also used.
// Draw a cut image: t. editPic. height = t. sHeight; t. editPic. width = t. sWidth; var ctx = t. editPic. getContext ('2d '); var images = new Image (); images. src = t. imgUrl; images. onload = function () {ctx. drawImage (images, t. sx, t. sy, t. sHeight, t. sWidth, 0, 0, t. sHeight, t. sWidth); // crop the image document. getElementById ('show _ edit '). getElementsByTagName ('img ') [0]. src = t. editPic. toDataURL (); // use the img label to display the cropped image}
Step 5: drag the cropping box and re-crop the image. When using the upload Avatar function, we hope to crop the desired image. Therefore, the cropping box must be continuously changed to crop the perfect image. The basic functions of cropping images have been implemented in the previous steps. Therefore, you need to follow the mouse movement to crop images in real time.
Drag: function () {var t = this; var draging = false; var startX = 0; var startY = 0; document. getElementById ('Cover _ box '). onmousemove = function (e) {// obtain the distance from the mouse to the background image var pageX = e. pageX-(t. regional. offsetLeft + this. offsetLeft); var pageY = e. pageY-(t. regional. offsetTop + this. offsetTop); // determines whether the mouse is in the cropping area: if (pageX> t. sx & pageX <t. sx + t. sWidth & pageY> t. sy & pageY <t. sy + t. sHeight) {this. style. cursor = 'move '; this. onmousedown = function () {draging = true; // records the last coordinate t. ex = t. sx; t. ey = t. sy; // record the coordinates startX = e when the mouse is pressed. pageX-(t. regional. offsetLeft + this. offsetLeft); startY = e. pageY-(t. regional. offsetTop + this. offsetTop);} window. onmouseup = function () {draging = false;} if (draging) {// coordinates of the cropping area when moving = positioning of the previous record + (current location of the mouse-position of the mouse pressed), the cropping area cannot exceed the region of the mask layer; if (t. ex + (pageX-startX) <0) {t. sx = 0;} else if (t. ex + (pageX-startX) + t. sWidth> t. imgWidth) {t. sx = t. imgWidth-t. sWidth;} else {t. sx = t. ex + (pageX-startX) ;}; if (t. ey + (pageY-startY) <0) {t. sy = 0;} else if (t. ey + (pageY-startY) + t. sHeight> t. imgHeight) {t. sy = t. imgHeight-t. sHeight;} else {t. sy = t. ey + (pageY-startY);} t. cutImage () ;}} else {this. style. cursor = 'auto ';}};}