1

I'm using FileReader to display in a <div> a file uploaded with an input type file. When the file is dropped in the field, I need to compressed the file and resize him. I used this code :

var width = source_img_obj.naturalWidth;
var height = source_img_obj.naturalHeight;
var quality = 90;

var maxWidth = 2000; // Max width for the image
var maxHeight = 2000;    // Max height for the image
var ratio = 0;  // Used for aspect ratio

// Check if the current width is larger than the max
if (width > maxWidth){
    ratio = maxWidth / width;   // get ratio for scaling image
    height = height * ratio;    // Reset height to match scaled image
    width = width * ratio;    // Reset width to match scaled image
}

// Check if current height is larger than max
if (height > maxHeight){
    ratio = maxHeight / height; // get ratio for scaling image
    width = width * ratio;    // Reset width to match scaled image
    height = height * ratio;    // Reset height to match scaled image
}

var cvs = document.createElement('canvas');
cvs.width = width;
cvs.height = height;
var ctx = cvs.getContext("2d").drawImage(source_img_obj, 0, 0, width, height);
var newImageData = cvs.toDataURL(mime_type, quality/100);
var result_image_obj = new Image();
result_image_obj.src = newImageData;

EDIT : FULL code is here

The finished file compressed is saved in result_image_obj, but before display this base64 image, I need to check the size of the final picture. So if the size is larger than 500kb I need to compress again the picture.

Is there a way to get the size (b, kb, mb..) of a base64 picture generated by canvas ?

Another question : Can we get the orientation of the picture uploaded with FileReader ? Because with some device portait picture are displayed in landscape orientation.

Thanks

Cracs
  • 425
  • 1
  • 8
  • 29
  • why do you pass the file into a FileReader at first? as I understand it, you are using the `readAsDataURL` method don't you? If so, why don't you use directly the `URL.createObjectURL(input.files[0])`? Also, to detect the orientation, you have to load the image data into an `img` element, but as you noticed, some devices will give you wrong values about which is the height and which is the width. One solution if you do use the capture, is to check the `window.orientation` property, but you can't be sure the picture was taken in the same orientation that the user leaves the input form. – Kaiido Sep 17 '15 at 00:50
  • For the resulted file size, do you need to keep it as a dataURL ? you will save about 37% if you convert it back to a blob. – Kaiido Sep 17 '15 at 00:54
  • I use readAsDAtaURL yes to display the picture uploaded after compressed and resize. I don't use `URL.createObjectURL(input.files[0])` because I don't want to use BLOB if I understood what this function mean. For the resulted size I need to display the picture compressed so the new picture with new size. For the orientation i found [exif.js](http://stackoverflow.com/questions/16221005/determine-orientation-of-photos-in-javascript) that can be good, I will try. – Cracs Sep 17 '15 at 07:36
  • You can see all my code [here](http://pastebin.com/0SvDmXMf) – Cracs Sep 17 '15 at 07:48
  • I still don't understand why you don't want to use blob (it's really close to the File object of the input you get), it will be one step less and you'll be able to get the real data size of the file, and save 37% of the base64 encoded version. – Kaiido Sep 17 '15 at 12:54

1 Answers1

2

You can find rough image size using:

var size = newImageData.length * 3 / 4; // size in bytes

if (size > 500 * 1024) {  // more than 500 kb
   // do something
}

Look here for more info: Base64 length calculation?

Community
  • 1
  • 1
lavrton
  • 18,973
  • 4
  • 30
  • 63