kate moss
kate moss

Reputation: 766

How to resize Image on HTML Canvas while loading from client side?

I am trying to control Image size whenever user upload an Image, so when user upload larger image like 1600x1600 it should be fixed in a canvas with w=500 and h=800, how can I do this in canvas, also image quality have to be same only resize in image.

How can I set maxwidth and maxHeight to control the Image size ?

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
  });
});
<head>

  <title>Jcrop Example</title>

  <link href="https://unpkg.com/[email protected]/dist/jcrop.css" rel="stylesheet" />
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">

  <script src="https://unpkg.com/[email protected]/dist/jcrop.js"></script>

</head>

<body>
  <div><a  id="save">Save</a>
    <input type="file" id="imageLoader" name="imageLoader" />
    <!-- add this for file picker -->
  </div>
  <div>

    <h1 style="font-family:Helvetica,sans-serif;">

      Image Crop <span style="color:lightgray;"></span>
    </h1>

    <img id="target" style="background-size: cover !important;">


  </div>
</body>

Upvotes: 0

Views: 385

Answers (1)

aleng
aleng

Reputation: 428

I'm not sure what is not working for you, but here I made a preview mode so you can see what's your crop result in canvas. If you wonder why the donwload not working, maybe it's SO snippets not allowed it, I'm not sure, but here you can test full working ecxample in jsfiddle

var jcp;
var save = document.getElementById('save');
var imageLoader = document.getElementById('imageLoader');
var img = document.getElementById("target");
var max_width = 500
var max_height = 500
var fileName = 'filename.png'
var changes

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 (let area of jcp.crops) {
      i++;
      let naturalWidth = img.naturalWidth;
      let naturalHeight = img.naturalHeight;
      let scaleX = naturalWidth / img.width
      let scaleY = naturalHeight / img.height

      let canvasSave = document.createElement("canvas");
      var ctxSave = canvasSave.getContext('2d');

      canvasSave.width = area.pos.w * scaleX
      canvasSave.height = area.pos.h * scaleY

      ctxSave.drawImage(img, -area.pos.x * scaleX, -area.pos.y * scaleY, naturalWidth, naturalHeight)

      var link = document.createElement('a');
      link.download = fileName;
      link.href = canvasSave.toDataURL("image/png")
      
      link.click();
      alert('file save')



    }
  }
};
Jcrop.load('target').then(img => {
  jcp = Jcrop.attach(img, {
    multi: true,
  });
  changes = img.nextSibling
  observer.observe(changes, config);

});
const callback = function(mutationsList, observer) {
  // Use traditional 'for loops' for IE 11
  for (const mutation of mutationsList) {
    if (mutation.type === 'childList') {
      console.log('A child node has been added or removed.');
    } else if (mutation.type === 'attributes') {
      updatePreview()
    }
  }
};
const observer = new MutationObserver(callback);
const config = {
  attributes: true,
  childList: true,
  subtree: true
};


function updatePreview() {
  if (jcp && jcp.active) {
    var i = 0;
    for (let area of jcp.crops) {
      canvas = document.getElementById("canvas");
      var ctx = canvas.getContext('2d');
      //for preview
      canvas.width = area.pos.w
      canvas.height = area.pos.h

      ctx.drawImage(img, -area.pos.x, -area.pos.y, img.width, img.height)

    }
  }
}
<head>

  <title>Jcrop Example</title>

  <link href="https://unpkg.com/[email protected]/dist/jcrop.css" rel="stylesheet" />
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">

  <script src="https://unpkg.com/[email protected]/dist/jcrop.js"></script>

</head>

<body>
  <div><a id="save">Save</a>
    <input type="file" id="imageLoader" name="imageLoader" />
    <!-- add this for file picker -->
  </div>
  <div>

    <h1 style="font-family:Helvetica,sans-serif;">

      Image Crop <span style="color:lightgray;"></span>
    </h1>

    <img id="target" style="background-size: cover !important;" width='500'>
    <div style='width:100%;'>
      <canvas id="canvas" style='border: 4px solid blue;' />
    </div>


  </div>
</body>

Upvotes: 1

Related Questions