Resize before upload?
-
Is it possible to resize the image before uploading, since phone camera images are so large these days? I was hoping to use the wfu_before_upload, wfu_before_file_check, or wfu_before_file_upload filters, but these don’t allow modification of the source image.
-
Hi, maybe you can use wfu_after_file_loaded filter.
This filter runs after the file has completely loaded on server. It provides the opportunity to perform custom checks on its contents and reject or accept it.
Have you tried it?
Regards
Nickolas
I was actually looking for something that resizes client-side. I can’t take a look at it right this moment, so maybe I’m misunderstanding, but it seems like I would need a hook that allows me to take the image file, modify it, and then pass it back to the main function.I didn’t see a hook that allows me to pass an image back.
Resizing can be done in client side as well. Do you have any specific Javascript libraries for image resizing?
Nickolas
Nothing specific. I can research it and post back here.
ok I have already prepared a piece of code that can do processing on the contents of a file before it is uploaded.
Nickolas
Ok, so I’ve been looking around at things and found a solution that works for me.
1. Following this StackOverflow, I created a function: resizePhotos(id, maxSize). I saved this to the file “client-resize.js” and enqueued the script as usual in my functions.php.
2. This function should fire at the onchange event of input #upfile_1 with id=’upfile_1′, and I have maxSize set to 500.
3. The function resizes the image and outputs it to a blob and a dataurl, which can be retrieved using the “imageResized” event (using “jQuery(document).on(“imageResized”, function (event) {…”)I’ve tested the function and verified that it can retrieve and resize the image when I run it manually in developer tools. What I can’t figure out is 1) how to actually add the function to the onchange event of #upfile_1 because I can’t figure out how to wait until #upfile_1 is loaded and 2)how to take the blob or dataurl and put it back into the form for uploading.
client-resize.js:
//Requires jQuery //Thanks to https://stackoverflow.com/users/689298/ferics2 //takes the upload element id ("upfile_1") and a maxSize to resize, ideally on a change event window.resizePhotos = function(id, maxSize){ console.log('resizing'); // Read in file var file = document.getElementById(id).files[0]; // Ensure it's an image if(file.type.match(/image.*/)) { console.log('An image has been loaded'); // Load the image var reader = new FileReader(); reader.onload = function (readerEvent) { var image = new Image(); image.onload = function (imageEvent) { // Resize the image var canvas = document.createElement('canvas'), max_size = maxSize, width = image.width, height = image.height; if (width > height) { if (width > max_size) { height *= max_size / width; width = max_size; } } else { if (height > max_size) { width *= max_size / height; height = max_size; } } canvas.width = width; canvas.height = height; canvas.getContext('2d').drawImage(image, 0, 0, width, height); var dataUrl = canvas.toDataURL('image/jpeg'); var resizedImage = dataURLToBlob(dataUrl); jQuery.event.trigger({ type: "imageResized", blob: resizedImage, url: dataUrl }); } image.src = readerEvent.target.result; } reader.readAsDataURL(file); } }; /* Utility function to convert a canvas to a BLOB */ var dataURLToBlob = function(dataURL) { var BASE64_MARKER = ';base64,'; if (dataURL.indexOf(BASE64_MARKER) == -1) { var parts = dataURL.split(','); var contentType = parts[0].split(':')[1]; var raw = parts[1]; return new Blob([raw], {type: contentType}); } var parts = dataURL.split(BASE64_MARKER); var contentType = parts[0].split(':')[1]; var raw = window.atob(parts[1]); var rawLength = raw.length; var uInt8Array = new Uint8Array(rawLength); for (var i = 0; i < rawLength; ++i) { uInt8Array[i] = raw.charCodeAt(i); } return new Blob([uInt8Array], {type: contentType}); } /* Handle image resized events */ jQuery(document).on("imageResized", function (event) { //var data = new FormData(jQuery("form[id*='uploadImageForm']")[0]); console.log('imageResized'); if (event.blob && event.url) { document.getElementById('upfile_1').files[0] = event.url; console.log(document.getElementById('upfile_1').files[0]); console.log(event.url); } });
`
Update:
I found the (obvious) answer to my first question (how to actually add the function to the onchange event of #upfile_1 because I can’t figure out how to wait until #upfile_1 is loaded). I just needed to use jQuery’s window.on(‘load’, function(){}) function, with some extra spice to handle when the user selects a file and then navigates away from the page before selecting the same file:jQuery(window).on('load', function() { /*resets the value to address the issue of navigating away from the page and choosing to upload the same file */ jQuery('#upfile_1').on('click touchstart' , function(){ jQuery(this).val(''); }); //Trigger now when you have selected any file jQuery("#upfile_1").change(function(e) { resizePhotos('upfile_1', 500) }); });
Now, I’m able to get resizePhotos() to run, which then triggers the “imageResized” event. That now reliably outputs a resized dataURL to the console, and my only issue is this:
How can I take the blob or dataurl and put it back into the form for uploading?
This question has one additional constraint: I can’t use the dataTransfer object because it’s not supported on iOS Safari, which is a dealbreaker. Neither
document.getElementById('upfile_1').files[0] = event.url;
nordocument.getElementById('upfile_1').files[0] = event.blob;
seem to work. My guess is that I’d have to send it via an ajax request, but maybe you know a better way.
- The topic ‘Resize before upload?’ is closed to new replies.