Intro: I have a post in which users can upload up to 8 images. My deployment method does not allow my total upload (total of all images to be more than 10mb). So I cannot use Pillow or other packages which reduce image size after upload. I was thinking If I use Javascript I can reduce the image size before I even submit the form. That way when I hit submit the images are already reduced and the total of all images is less than 9mb (just to be on the safe side)
The code is borrowed from :
Use https://github.com/josefrichter/resize/blob/master/public/preprocess.js
I am not sure how to use them. below is my form template
This is just for my main post_image I still have to figure out how to reduce the size of my formset images
{% extends 'posts/post_base.html' %}
{% load bootstrap3 %}
{% load staticfiles %}
{% block postcontent %}
<h2> Add a new Post</h2>
<form action="" method="post" enctype="multipart/form-data" id="form">
{% csrf_token %}
{% bootstrap_form form %}
<img id="preview" src="" width="100" />
{{formset.management_form}}
{% for f in formset %}
<div style="border-style: inset; padding:20px;">
<p class="text-warning">Extra Image {{forloop.counter}}</p>
{% bootstrap_form f %}
<img src="" width="60" id="preview-extra{{forloop.counter}}"/>
</div>
{% endfor %}
<br/><br/><input type="submit" class="btn btn-primary" value="Post"/>
</form>
<script >
var fileinput = document.getElementById('fileinput');
var max_width = 500;
var max_height = 500;
var preview = document.getElementById('preview');
var form = document.getElementById('form');
function processfile(file) {
if( !( /image/i ).test( file.type ) )
{
alert( "File "+ file.name +" is not an image." );
return false;
}
// read the files
var reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onload = function (event) {
// blob stuff
var blob = new Blob([event.target.result]); // create blob...
window.URL = window.URL || window.webkitURL;
var blobURL = window.URL.createObjectURL(blob); // and get it is URL
// helper Image object
var image = new Image();
image.src = blobURL;
//preview.appendChild(image); // preview commented out, I am using the canvas instead
image.onload = function() {
// have to wait till it is loaded
var resized = resizeMe(image); // send it to canvas
var newinput = document.createElement("input");
newinput.type = 'hidden';
newinput.name = 'images[]';
newinput.value = resized; // put result from canvas into new hidden input
form.appendChild(newinput);
}
};
}
function readfiles(files) {
// remove the existing canvases and hidden inputs if user re-selects new pics
var existinginputs = document.getElementsByName('images[]');
var existingcanvases = document.getElementsByTagName('canvas');
// it is a live list so removing the first element each time DOMNode.prototype.remove = function() {this.parentNode.removeChild(this);}
while (existinginputs.length > 0) {
form.removeChild(existinginputs[0]);
preview.removeChild(existingcanvases[0]);
}
for (var i = 0; i < files.length; i++) {
processfile(files[i]); // process each file at once
}
fileinput.value = ""; //remove the original files from fileinput
// TODO remove the previous hidden inputs if user selects other files
}
// this is where it starts. event triggered when user selects files
fileinput.onchange = function(){
if ( !( window.File && window.FileReader && window.FileList && window.Blob ) ) {
alert('The File APIs are not fully supported in this browser.');
return false;
}
readfiles(fileinput.files);
};
// === RESIZE ====
function resizeMe(img) {
var canvas = document.createElement('canvas');
var width = img.width;
var height = img.height;
// calculate the width and height, constraining the proportions
if (width > height) {
if (width > max_width) {
//height *= max_width / width;
height = Math.round(height *= max_width / width);
width = max_width;
}
} else {
if (height > max_height) {
//width *= max_height / height;
width = Math.round(width *= max_height / height);
height = max_height;
}
}
// resize the canvas and draw the image data into it
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, width, height);
preview.appendChild(canvas); // do the actual resized preview
return canvas.toDataURL("image/jpeg",0.7); // get the data from canvas as 70% JPG (can be also PNG, etc.)
}
</script>
{% endblock %}
I wanted image size to be reduced to 400kb. if the user uploads less than that then no resize needed
On trying your solution getting the below error