1

I have a web application that allows user to upload tons of images, My goal is to reduce the hosting fees AWS are going to charge me by shrink the image size users uploaded,

Currently i set the limit to 1MB using simple Js, I am not really a frontend developer, So How hard it is to create a javascript solution that automatically shrinks the image size? Is this can be done easily?

If not, then my other two options are Django and AWS UI, the backend is Django, But Django can only process the image once it reaches the backend, So if this happens, Would my aws cost increase?

Finally it's the AWS solution, I don't know how to do it yet, Maybe using something called lambda? Is it completely free? If it keeps my cost down and easy to set up then this is it?

Or would it be wise just to use simple javascript? is this can be easily implemented? like copy and paste code less than 50lines of code then it's automatically solved?

John Rotenstein
  • 241,921
  • 22
  • 380
  • 470
Z.Q
  • 125
  • 7
  • "Is it completely free?" - no its not. – Marcin May 14 '21 at 01:01
  • @Marcin, But the whole point is to reduce the cost, If aws is not free then what are my options? Javascript? Is this can be done easily by a few lines of js code? – Z.Q May 14 '21 at 01:03
  • Lambda would be first choice to consider, but its price depends on how many images you process, how big are those images, how long it would take to process an image, how much ram do you need, etc. None of this info is given in your question. its only speculation. – Marcin May 14 '21 at 01:05
  • @Marcin well......But its not free, my point here is to reduce the cost, I don't wanna pay large bills, If javascript or django backend can do this for free then why use lambda – Z.Q May 14 '21 at 01:07
  • nothing at AWS is free at the end of the day. You may have some discounts or some "free tier" free use for a moment. The cost of using lambda, if any, maybe be compenstated by smaller s3 storage bills, outgoing traffic, etc. Only you know what is your application and how much it costs to store the images, etc. – Marcin May 14 '21 at 01:09
  • @Marcin, i get the point, it reduces the cost, but in comparison, Javascript would be a free solution, further lower my cost no? – Z.Q May 14 '21 at 01:12
  • Yes, it would be free, but also easily circumvented as anyone who would care could disable it in your front end code. – Marcin May 14 '21 at 01:14
  • @Marcin Then wouldn't it be a better solution to use js at the frontend and using lamba in the same time to further reduce the cost? and maybe some django backend solution? since its backend, it's like a free version of lamba no? but harder to implement? – Z.Q May 14 '21 at 01:19
  • You can use this answer, https://stackoverflow.com/a/20382559/12415287 – Prosy Arceno May 14 '21 at 01:20
  • @ProsyArceno i am looking into it, I used canvas for the captcha, Is the idea of using canvas something like remember the image pixels and redraw it? so the size would get smaller? – Z.Q May 14 '21 at 01:25
  • I wasn't really referring to the canvas, it's the method of resizing the image. You can view my answer as an example based of the link I showed. – Prosy Arceno May 14 '21 at 01:53
  • https://stackoverflow.com/a/51810740/1008999 – Endless May 14 '21 at 21:55
  • @Endless Very good point, I just learned that canvas actually does INCREASE the file size if kept original quality, As of now the only js solution i know for sure works is Compress.js, But it's an npm package, I have no clue how to use it without using something like "npm install" – Z.Q May 15 '21 at 15:42

2 Answers2

1

Here's a working example based on my comment:

/**
 * Resize a base 64 Image
 * @param {String} base64 - The base64 string (must include MIME type)
 * @param {Number} newWidth - The width of the image in pixels
 * @param {Number} newHeight - The height of the image in pixels
 */

const toBase64 = file => new Promise((resolve, reject) => {
  const reader = new FileReader();
  reader.readAsDataURL(file);
  reader.onload = () => resolve(reader.result);
  reader.onerror = error => reject(error);
});

async function Main() {
  const file = document.querySelector('.file').files[0];
  const newFile = await toBase64(file);

  document.body.append("Before: ");
  let before = document.createElement("img");
  before.src = newFile;
  document.body.appendChild(before);

  resizeBase64Img(newFile, 200, 200).then(resized => {
    let img = document.createElement("img");
    img.src = resized;
    document.body.appendChild(img);
  });
}

function resizeBase64Img(base64, newWidth, newHeight) {
  return new Promise((resolve, reject) => {
    var canvas = document.createElement("canvas");
    canvas.style.width = newWidth.toString() + "px";
    canvas.style.height = newHeight.toString() + "px";
    let context = canvas.getContext("2d");
    let img = document.createElement("img");
    img.src = base64;
    img.onload = function() {
      context.scale(newWidth / img.width, newHeight / img.height);
      context.drawImage(img, 0, 0);
      resolve(canvas.toDataURL());
    }
  });
}

document.querySelector(".file").addEventListener("input", Main);
<input class="file" type="file">
Prosy Arceno
  • 2,616
  • 1
  • 8
  • 32
  • I don't fully understand your code, The resize part does work, But it doesn't replace the image file thats being uploaded, What do i need to add so that it replaced the image file uploaded with the new resized image – Z.Q May 14 '21 at 03:27
  • How are you uploading your file? dataURL? – Prosy Arceno May 14 '21 at 03:31
  • .............its the basic html way of uploading an image, a button that says upload image, a user clicks it and then select the image he wants to upload via a django generated form – Z.Q May 14 '21 at 03:39
  • So you're using Ajax? – Prosy Arceno May 14 '21 at 04:15
  • No, Idk how exactly Django does the connection with the frontend, I have not written any ajax code ever – Z.Q May 15 '21 at 08:00
  • I learned how your code works now and i know how to replace the image with newly generated dataURL, However the quality of the image became unusable if you shrink an image of 1mb in size down to 50kb, The image is basically destroyed, There are other JS ways to achieve such goal without reducing the image appearance, Not sure how its done. – Z.Q May 15 '21 at 15:35
  • ps: I think canvas actually increase the file size if quality remains the same – Z.Q May 15 '21 at 15:35
0

HTML5 Canvas Resize (Downscale) Image High Quality?

ImageMagick on js

JavaScript library similar to Imagemagick

Sorry if this bothers you, I can't use comment yet

  • It seems to involve npm package, seems pretty complicated, Im not really familier with js, can it be done just by using simple javascript or Jquery? – Z.Q May 14 '21 at 01:15