PS: Is it not a research kind of question! I have been trying to do this from very long time.
I am trying to make web based an image editor where user can select multiple cropping area and after selection save/download all the image area. like below.
As of now I discovered two libraries
1.Cropper.JS where is only single selection feature is available.
2.Jcrop where only single selection area restrictions.
I am currently using cropper.Js but it seems impossible for me to make multiple selection cropping. Any help is much appreciated.if any other method/library available in JavaScript, Angular or PHP or reactJS for multiple image area selection and crop and download in one go as in the image below.
As per @Keyhan Answer I am Updating my Jcrop library Code
<div style="padding:0 5%;"> <img id="target" src="https://d3o1694hluedf9.cloudfront.net/market-750.jpg"> </div> <button id="save">Crop it!</button> <link rel="stylesheet" href="https://unpkg.com/jcrop/dist/jcrop.css"> <script src="https://unpkg.com/jcrop"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
JavaScript
<script> setImage(); var jcp; var jcp; Jcrop.load('target').then(img => { //You can enable multiple cropping with this line: jcp = Jcrop.attach(img, { multi: true }); }); // to fix security issue when trying to convert to Data URI function setImage() { document.getElementById('target').setAttribute('crossOrigin', 'anonymous'); document.getElementById('target').src = 'https://d3o1694hluedf9.cloudfront.net/market-750.jpg'; } var link = document.getElementById('save'); link.onclick = function () { //we check if at least one crop is available if (jcp.active) { var i = 0; var fullImg = document.getElementById("target"); //we are looping cropped areas for (area of jcp.crops) { i++; //creating temp canvas and drawing cropped area on it canvas = document.createElement("canvas"); canvas.setAttribute('width', area.pos.w); canvas.setAttribute('height', area.pos.h); ctx = canvas.getContext("2d"); ctx.drawImage(fullImg, area.pos.x, area.pos.y, area.pos.w, area.pos.h, 0, 0, area.pos.w, area.pos.h); //creating temp link for saving/serving new image temp = document.createElement('a'); temp.setAttribute('download', 'area' + i + '.jpg'); temp.setAttribute('href', canvas.toDataURL("image/jpg").replace("image/jpg", "image/octet-stream")); temp.click(); } } }; </script>
Advertisement
Answer
I tried to explain the code with comments:
var jcp; Jcrop.load('target').then(img => { //You can enable multiple cropping with this line: jcp = Jcrop.attach(img,{multi:true}); }); //assuming you have a button with id="save" for exporting cropped areas var link=document.getElementById('save'); link.onclick = function(){ //we check if at least one crop is available if(jcp.active){ var i=0; var fullImg = document.getElementById("target"); //we are looping cropped areas for(area of jcp.crops){ i++; //creating temp canvas and drawing cropped area on it canvas = document.createElement("canvas"); canvas.setAttribute('width',area.pos.w); canvas.setAttribute('height',area.pos.h); ctx = canvas.getContext("2d"); ctx.drawImage(fullImg, area.pos.x, area.pos.y, area.pos.w, area.pos.h, 0, 0, area.pos.w, area.pos.h); //creating temp link for saving/serving new image temp = document.createElement('a'); temp.setAttribute('download', 'area'+i+'.jpg'); temp.setAttribute('href', canvas.toDataURL("image/jpg").replace("image/jpg", "image/octet-stream")); temp.click(); } } };
EDIT: As you commented it would be nicer if we have local image loader, we can add a file input to our html
<img id="target" /> <br/> <input type="file" id="imageLoader" name="imageLoader"/><!-- add this for file picker --> <button id="save">save</button>
and a function to our js to handle it
var jcp; var save=document.getElementById('save'); var imageLoader = document.getElementById('imageLoader'); var img = document.getElementById("target"); imageLoader.onchange=function handleImage(e){//handling our image picker <input>: var reader = new FileReader(); reader.onload = function(event){ img.src = event.target.result; } reader.readAsDataURL(e.target.files[0]); } save.onclick = function(){ if(jcp&&jcp.active){ var i=0; for(area of jcp.crops){ i++; canvas = document.createElement("canvas"); canvas.setAttribute('width',area.pos.w); canvas.setAttribute('height',area.pos.h); ctx = canvas.getContext("2d"); ctx.drawImage(img, area.pos.x, area.pos.y, area.pos.w, area.pos.h, 0, 0, area.pos.w, area.pos.h); temp = document.createElement('a'); temp.setAttribute('download', 'area'+i+'.jpg'); temp.setAttribute('href', canvas.toDataURL("image/jpg").replace("image/jpg", "image/octet-stream")); temp.click(); } } }; Jcrop.load('target').then(img => { jcp = Jcrop.attach(img,{multi:true}); });