Using canvas to shrink images for Google Cloud Vision
I've started using Google Cloud Vision for running text detection on OpenBenches images. There's just one problem - Google limits the size of the files that it will accept to 4MB.
Why? Who knows!
Obviously, it's easy to shrink an image server-side, but how do we do it in the browser?
First, let's take a bog-standard file chooser and add a <canvas>
element.
<input id="userFile" type="file" accept="image/jpeg" />
<canvas id="shrink"></canvas>
Next, when the user chooses a file, draw it on the canvas at half the resolution of the original file.
var input = document.getElementById('userFile');
input.addEventListener('change', drawImage, false);
function drawImage(e) {
// The File
var file = e.target.files[0];
var reader = new FileReader();
// The Canvas
var canvas = document.getElementById("shrink");
var ctx = canvas.getContext('2d');
// The Image
var img = new Image();
// Once the file has been read, set it as the image's source
reader.readAsDataURL(file);
reader.onloadend = function () {
img.src = reader.result;
}
// Once the image has been set, draw it on the canvas
img.onload = function() {
// Scale the canvas to be half the size of the image
// You can change the "/2" to be whatever size you want
ctx.canvas.width = img.width /2;
ctx.canvas.height = img.height /2;
// Draw the image onto the canvas
ctx.drawImage(img, 0, 0, ctx.canvas.width, ctx.canvas.height);
}
}
Here's the clever part! We can take the 2D image on the canvas and turn that into a JPG! In this specific example, the quality is set to 75% - which reduces the files size still further. This uses .toDataURL()
.
var smallImage = canvas.toDataURL('image/jpeg', 0.75);
Now smallImage
will contain "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDA...."
A much smaller file than the original.
This representation of the file can then be POST
ed to Google Cloud Vision.