HTML5 Local crop image

Source: Internet
Author: User
Tags crop image

Recently have time to understand the next HTML5 API, found that Sina Weibo avatar settings are implemented using canvas, and the previous period of time to understand the next HTML5 file API to use the files API FileReader to realize the upload more HTML5 fun, Try writing this function right when you're learning canvas.

Below, I wrote a demo of my own, the code is less written, many details will not be processed. If there are inappropriate places to ask for advice, thank you ^_^ ^_^

function Realization Step:

One: Get the file, read the file and generate the URL

Two: Use canvas to draw pictures based on container size

Three: Draw a matte layer using canvas

Four: Draw a cropped picture using canvas

V: Drag the Crop box to re-crop the picture

PS: Because it is the first to write the demo and then write this article, so the code is directly from the code inside a paragraph copy, pay attention to this object oh

The first step: Get the file, read the file, and generate the URL:

Here I use the file API inside the HTML5 to handle the local files upload, because this can not need to upload the image to the server, and then the server back to the image address to do a preview, see: Use the file API FileReader 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 completes successfully. Postfile.paintimage ( OFREvent.target.result);//pass the preview image URL to the function};

  

Step Two: use canvas to draw pictures based on container size

FileReader, who used the file API in the previous step, has already got the address to upload the image, which needs to be drawn using canvas. Why not just insert img here and redraw it with canvas, isn't it superfluous? actually otherwise If using IMG to insert the page directly, you can not adapt to the center, if you use canvas to draw pictures, not only can make the picture Adaptive center and can be scaled, and convenient to the picture coordinates, size size to the subsequent mask layer, so that the image coordinates and the size of the picture to draw the mask layer.

Here is a little attention to the DrawImage method of the canvas . Resources 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 () {//scale the picture if the picture is wider than the container, the picture width is high = the width of the original picture. )//If the width or height of the picture is larger than the container, the width or height = width or height of the container, and the other height or width is scaled proportionally// T.imgwidth: The width of the picture after drawing; T.imgheight: The height of the picture after painting; T.PX: The x-axis of the picture after it is drawn; t.py: the y-axis of the picture after painting 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.imgW Idth = img.width > img.height? T.regional.offsetwidth:pwidth;t.imgheight = img.height > img.width? T.regional.offsetheight:pheight;} The coordinates of the picture t.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);//Use canvas to draw a picture without inserting the background image directly, to adjust the size of the picture in the desired frame T.imgurl = T.getimage.todataurl ();// Store canvas-drawn image address t.cutimage (); T.drag ();};},

  

The effect comes out like this:

Step Three: draw a matte layer using canvas

In the previous step, we have drawn the background map that needs to be cropped, and now we need to draw a mask layer based on the coordinates and dimensions of the background map to cover the background, and use the canvas's Clearrect method to clear out a clipping area so that it is contrasted with the non-clipping place.

(The mask layer here is just for the display effect and does not work to crop the picture.) I wonder if this step can be removed directly? Have to know the children shoes trouble tell me. )

Draw 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);

 

Fourth Step: draw a cropped picture using canvas

In the third step, the mask layer is drawn, but the mask layer does not have the ability to cut, just to show the clipping area and the non-clipping region of the contrast, so here began to do the function of cutting pictures. Also use the DrawImage method to canvas.

Draw Cut Picture: T.editpic.height = T.sheight;t.editpic.width = T.swidth;var CTX = T.editpic.getcontext (' 2d '); var images = new Im Age (); 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 picture document.getElementById (' Show_edit '). getElementsByTagName (' img ') [0].SRC = T.editpic.todataurl (); Use the IMG tag to display the cropped image}

  

Fifth Step: Drag the Crop box to re-crop the picture

When using the upload Avatar feature we want to be able to crop to a satisfactory image, so the cropping box needs to be constantly changed to cut out the perfect picture. The first few steps have already cut the basic ability of the picture to make, so what needs to do now is to crop the box to follow the mouse move to cut the picture in real time.

Drag:function () {var t = This;var draging = False;var StartX = 0;var starty = 0;document.getelementbyid (' Cover_box '). Onmo  Usemove = function (e) {//Get mouse to background picture distance var PageX = E.pagex-(t.regional.offsetleft + this.offsetleft); var pagey = E.pagey -(t.regional.offsettop + this.offsettop);//Determine if the mouse is in the cropping area: if (PageX > T.sx && PageX < T.SX + T.swidth &A mp;& 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;//Records the coordinates of the mouse press time STARTX = E.pagex-(t.regional.offsetleft + this.offsetl) EFT); starty = E.pagey-(t.regional.offsettop + this.offsettop);} Window.onmouseup = function () {draging = false;} if (draging) {//move crop area coordinates = Last record's location + (current mouse position-where the mouse is pressed), the cropping area cannot exceed the area of the matte 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.sh Eight;} else {t.sy = T.ey + (pagey-starty);} T.cutimage ();}} Else{this.style.cursor = ' auto ';}};}

  

The picture is as follows:

The demo complete code is as follows:

HTML and CSS:

#label {border:1px solid #ccc; Background-color: #fff; text-align:center;height:300px; width:300px;margin:20px auto; Position:relative;} #get_image {Position:absolute;} #edit_pic {position:absolute;display:none;background: #000;} #cover_box {position:absolute;z-index:9999;display:none;top:0px;left:0px;} #show_pic {height:100px;width:100px;border:2px solid #000; overflow:hidden;margin:0 Auto;}

  

<input type= "File" name= "file" id= "Post_file" ><div id= "label" ><canvas id= "Get_image" ></canvas ><span><canvas id= "Cover_box" ></canvas><canvas id= "Edit_pic" ></canvas></span ></div><div id= "Show_edit" ></div>

 

Js:

varPostfile ={init:function() {        vart = This; T.regional= document.getElementById (' label '); T.getimage= document.getElementById (' Get_image '); T.editpic= document.getElementById (' Edit_pic '); T.editbox= document.getElementById (' Cover_box '); T.PX= 0;//background image x axist.py = 0;//background picture Y axisT.SX = 15;//crop Area X-axisT.sy = 15;//crop area y-axisT.sheight = 100;//Crop Area HeightT.swidth = 100//Crop area widthdocument.getElementById (' Post_file '). AddEventListener ("Change", T.handlefiles,false); }, Handlefiles:function() {        varFileList = This. files[0]; varOfreader =NewFileReader ();        Ofreader.readasdataurl (fileList); Ofreader.onload=function(ofrevent) {//called when the read operation completes successfully.Postfile.paintimage (OFREvent.target.result);//pass the preview image URL to the function        }; }, Paintimage:function(URL) {vart = This; varCreatecanvas = T.getimage.getcontext ("2d"); varIMG =NewImage (); IMG.SRC=URL; Img.onload=function(){            //Scale the picture (if the picture is wider than the container), the picture width is high = the width of the original picture. )            //if the width or height of the picture is larger than the container, the width or height = the width or height of the container, and the other height or width is scaled proportionally            //t.imgwidth: The width of the picture after drawing; T.imgheight: The height of the picture after painting; T.PX: The x-axis of the picture after drawing; t.py: the y-axis of the picture after drawing            if(Img.width < t.regional.offsetwidth && Img.height <t.regional.offsetheight) {t.imgwidth=Img.width; T.imgheight=Img.height; } Else {                varPWidth = img.width/(Img.height/t.regional.offsetheight); varPheight = img.height/(Img.width/t.regional.offsetwidth); T.imgwidth= img.width > Img.height?T.regional.offsetwidth:pwidth; T.imgheight= img.height > Img.width?T.regional.offsetheight:pheight; }            //the coordinates of the pictureT.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);//use canvas to draw a picture instead of inserting a background image directly to adjust the size of the picture in the desired frameT.imgurl = T.getimage.todataurl ();//Save a canvas-drawn picture addressT.cutimage ();        T.drag ();    }; }, Cutimage:function() {        vart = This; //To draw a 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; varCover = 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); //To draw a cut Picture:T.editpic.height =T.sheight; T.editpic.width=T.swidth; varCTX = T.editpic.getcontext (' 2d '); varImages =NewImage (); 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 a picturedocument.getElementById (' Show_edit '). getElementsByTagName (' img ') [0].SRC =T.editpic.todataurl (); }}, drag:function() {        vart = This; varDraging =false; varStartX = 0; varStarty = 0; document.getElementById (' Cover_box '). onmousemove =function(e) {//get mouse-to-background image distance            varPageX = E.pagex-(T.regional.offsetleft + This. offsetleft); varPagey = E.pagey-(t.regional.offsettop + This. OffsetTop); //determine if 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; //record the last coordinateT.ex =t.sx; T.ey=T.sy; //record the coordinates of the mouse when pressedStartX = E.pagex-(T.regional.offsetleft + This. offsetleft); Starty= E.pagey-(t.regional.offsettop + This. OffsetTop); } window.onmouseup=function() {draging=false; }                if(draging) {//the coordinates of the cropped area when moving = the location of the last record + (the position of the current mouse-where the mouse is pressed), the clipping area cannot exceed the area 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 ';    }        }; }}
View Code

HTML5 Local crop image

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.