Image resizing, good library needed

First of all - the problem


I am developing a web application that allows the user to take a picture using a smartphone, tablet, or simply view the image on their PC. I need to upload this file to my database which works fine IF , the image is small enough.

After experimenting a bit with some photos, I found out that a smartphone takes a picture of at least 1MB in size, and this is a way to upload a lot to my database.

Loading is done as follows:
1. Convert the image to Base64 encoding.
2. Send string to array (containing string in chunks) in WebAPI
3. Append strings to one and convert them to byte array.

I noticed that if the file is around 70-90KB, this will be the maximum file size that can be inserted into the database. The moment I have a file larger than 100kb the insert failed.

So I am looking for a good resizing library to resize the selected image. I don't know if this is possible, but everything should be done on the client side.

Technology


I am using Javascript / jQuery and AngularJS for the client side and VB.NET for my WebAPI. This is because I am doing an internship and have no other choice to use VB.NET.

But that has nothing to do with the problem, I just need to find a way to shrink / resize / minimize the selected file so that it can be loaded into the database.

Loading is done via $ http.post () from AngularJS.

If anyone can advise a library, take care to help the second programmer with some basic code example? I am mostly having problems with how to use a plugin or library because I am completely new to this. And I would appreciate it if you guys could provide me with at least some information to get me on track.

Thanks in advance!

Sorry I couldn't provide any code or anything else, this is more of an informative question than a coding issue. It might show up if I have a library that I can use. Also, if there are any comments, I will consider them because I have a deadline and little time to start fixing small problems. Most of them still work, except for the problem with this image.

+3


source to share


1 answer


You can use an HTML5 canvas element to frame an image and then resize it accordingly.

You create canvas

on the fly and perform pixel operations on it - so don't worry about it not showing up anywhere in the DOM - think of it like a virtual canvas

Here's a little script I wrote a while ago (with some help from another SO question that I don't really remember) - it allows you to do this while maintaining the aspect ratio of an image:

Arguments

  • You provide image

    directly to it
  • You provide maxWidth

    / maxHeight

    and keep at least one of 2
  • It also allows you to rotate the image by defining a parameter degrees

    (which would be really useful on mobile devices, as various devices provide randomly rotated images - you will find out about this difficult soon if you are dealing with mobile devices)

Returns




function resizeImg(img, maxWidth, maxHeight, degrees) {
  var imgWidth = img.width,
    imgHeight = img.height;

  var ratio = 1,
    ratio1 = 1,
    ratio2 = 1;
  ratio1 = maxWidth / imgWidth;
  ratio2 = maxHeight / imgHeight;

  // Use the smallest ratio that the image best fit into the maxWidth x maxHeight box.
  if (ratio1 < ratio2) {
    ratio = ratio1;
  } else {
    ratio = ratio2;
  }
  var canvas = document.createElement("canvas");
  var canvasContext = canvas.getContext("2d");
  var canvasCopy = document.createElement("canvas");
  var copyContext = canvasCopy.getContext("2d");
  var canvasCopy2 = document.createElement("canvas");
  var copyContext2 = canvasCopy2.getContext("2d");
  canvasCopy.width = imgWidth;
  canvasCopy.height = imgHeight;
  copyContext.drawImage(img, 0, 0);

  // init
  canvasCopy2.width = imgWidth;
  canvasCopy2.height = imgHeight;
  copyContext2.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvasCopy2.width, canvasCopy2.height);


  var rounds = 1;
  var roundRatio = ratio * rounds;
  for (var i = 1; i <= rounds; i++) {


    // tmp
    canvasCopy.width = imgWidth * roundRatio / i;
    canvasCopy.height = imgHeight * roundRatio / i;

    copyContext.drawImage(canvasCopy2, 0, 0, canvasCopy2.width, canvasCopy2.height, 0, 0, canvasCopy.width, canvasCopy.height);

    // copy back
    canvasCopy2.width = imgWidth * roundRatio / i;
    canvasCopy2.height = imgHeight * roundRatio / i;
    copyContext2.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvasCopy2.width, canvasCopy2.height);

  } // end for

  canvas.width = imgWidth * roundRatio / rounds;
  canvas.height = imgHeight * roundRatio / rounds;
  canvasContext.drawImage(canvasCopy2, 0, 0, canvasCopy2.width, canvasCopy2.height, 0, 0, canvas.width, canvas.height);


  if (degrees == 90 || degrees == 270) {
    canvas.width = canvasCopy2.height;
    canvas.height = canvasCopy2.width;
  } else {
    canvas.width = canvasCopy2.width;
    canvas.height = canvasCopy2.height;
  }

  canvasContext.clearRect(0, 0, canvas.width, canvas.height);
  if (degrees == 90 || degrees == 270) {
    canvasContext.translate(canvasCopy2.height / 2, canvasCopy2.width / 2);
  } else {
    canvasContext.translate(canvasCopy2.width / 2, canvasCopy2.height / 2);
  }
  canvasContext.rotate(degrees * Math.PI / 180);
  canvasContext.drawImage(canvasCopy2, -canvasCopy2.width / 2, -canvasCopy2.height / 2);


  var dataURL = canvas.toDataURL();
  return dataURL;
}

      


And here's a piece of working code that lets you load from your filesystem and resize on the fly:

/*
-------------------------------
-------HANDLE FILE UPLOAD------
-------------------------------
*/

var input = document.getElementById('input');
input.addEventListener('change', handleFiles);

function handleFiles(e) {
  var img = new Image;
  img.src = URL.createObjectURL(e.target.files[0]);
  img.onload = function() {
    var base64String = resizeImg(img, 300, 300, 0); //HERE IS WHERE THE FUNCTION RESIZE IS CALLED!!!!
    alert(base64String);
    document.getElementById('previewImg').src = base64String;
  }
}



/*
-------------------------------
-------RESIZING FUNCTION-------
-------------------------------
*/


function resizeImg(img, maxWidth, maxHeight, degrees) {
  var imgWidth = img.width,
    imgHeight = img.height;

  var ratio = 1,
    ratio1 = 1,
    ratio2 = 1;
  ratio1 = maxWidth / imgWidth;
  ratio2 = maxHeight / imgHeight;

  // Use the smallest ratio that the image best fit into the maxWidth x maxHeight box.
  if (ratio1 < ratio2) {
    ratio = ratio1;
  } else {
    ratio = ratio2;
  }
  var canvas = document.createElement("canvas");
  var canvasContext = canvas.getContext("2d");
  var canvasCopy = document.createElement("canvas");
  var copyContext = canvasCopy.getContext("2d");
  var canvasCopy2 = document.createElement("canvas");
  var copyContext2 = canvasCopy2.getContext("2d");
  canvasCopy.width = imgWidth;
  canvasCopy.height = imgHeight;
  copyContext.drawImage(img, 0, 0);

  // init
  canvasCopy2.width = imgWidth;
  canvasCopy2.height = imgHeight;
  copyContext2.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvasCopy2.width, canvasCopy2.height);


  var rounds = 1;
  var roundRatio = ratio * rounds;
  for (var i = 1; i <= rounds; i++) {


    // tmp
    canvasCopy.width = imgWidth * roundRatio / i;
    canvasCopy.height = imgHeight * roundRatio / i;

    copyContext.drawImage(canvasCopy2, 0, 0, canvasCopy2.width, canvasCopy2.height, 0, 0, canvasCopy.width, canvasCopy.height);

    // copy back
    canvasCopy2.width = imgWidth * roundRatio / i;
    canvasCopy2.height = imgHeight * roundRatio / i;
    copyContext2.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvasCopy2.width, canvasCopy2.height);

  } // end for

  canvas.width = imgWidth * roundRatio / rounds;
  canvas.height = imgHeight * roundRatio / rounds;
  canvasContext.drawImage(canvasCopy2, 0, 0, canvasCopy2.width, canvasCopy2.height, 0, 0, canvas.width, canvas.height);


  if (degrees == 90 || degrees == 270) {
    canvas.width = canvasCopy2.height;
    canvas.height = canvasCopy2.width;
  } else {
    canvas.width = canvasCopy2.width;
    canvas.height = canvasCopy2.height;
  }

  canvasContext.clearRect(0, 0, canvas.width, canvas.height);
  if (degrees == 90 || degrees == 270) {
    canvasContext.translate(canvasCopy2.height / 2, canvasCopy2.width / 2);
  } else {
    canvasContext.translate(canvasCopy2.width / 2, canvasCopy2.height / 2);
  }
  canvasContext.rotate(degrees * Math.PI / 180);
  canvasContext.drawImage(canvasCopy2, -canvasCopy2.width / 2, -canvasCopy2.height / 2);


  var dataURL = canvas.toDataURL();
  return dataURL;
}
      

/*
-------------------------------
-------UNNECESSARY CSS---------
-------------------------------
*/

@import url(http://fonts.googleapis.com/css?family=Lato);
 .container {
  margin: 0 auto;
  width: 400px;
  height: 400px;
  box-shadow: 1px 1px 1px 1px gray;
}
h3,
h4,
h5,
h6 {
  margin: 4px !important;
}
.container,
.container * {
  display: block;
  margin: 12px auto;
  font-family: 'Lato';
}
.header {
  background-color: #2196F3;
  padding: 12px;
  color: #fff;
}
.container input {
  width: 128px;
  height: 32px;
  cursor: pointer;
}
.container img {
  display: block;
  margin: 12px auto;
}
      

<div class="container">
  <div class="header">
    <h3>Choose a file</h3>
    <h6>and I will alert back to you the base64 string of it resized version</h6>
  </div>
  <input type="file" id="input" />
  <hr>
  <h5>Image Preview:</h5>
  <img id="previewImg" src="" />

</div>
      

Run codeHide result


+3


source







All Articles