-
-
Save ORESoftware/ba5d03f3e1826dc15d5ad2bcec37f7bf to your computer and use it in GitHub Desktop.
| // Using this code, we can retrieve an image from a user's filesystem, resize the image, and then upload the image | |
| // to a server using AJAX. Because we use base64 encoding, we can just include the image data as just another string value | |
| // in a JSON payload. | |
| // So we can use AJAX to send the file to a server, which is convenient. | |
| // We have one line of relevant html | |
| // get file in the first place => <input type="file" custom-on-change="onAcqImageFileChange" class="form-control"> | |
| $scope.onAcqImageFileChange = function (e) { | |
| e.preventDefault(); | |
| var file = e.target.files[0]; | |
| $scope.acqImageFile = file; // store reference to file | |
| }; | |
| function convertToBase64(file, cb) { | |
| var reader = new FileReader(); | |
| reader.onload = function (e) { | |
| cb(null, e.target.result) | |
| }; | |
| reader.onerror = function (e) { | |
| cb(e); | |
| }; | |
| reader.readAsDataURL(file); | |
| } | |
| function resizeImage(base64Str) { | |
| var img = new Image(); | |
| img.src = base64Str; | |
| var canvas = document.createElement('canvas'); | |
| var MAX_WIDTH = 400; | |
| var MAX_HEIGHT = 350; | |
| var width = img.width; | |
| var height = img.height; | |
| if (width > height) { | |
| if (width > MAX_WIDTH) { | |
| height *= MAX_WIDTH / width; | |
| width = MAX_WIDTH; | |
| } | |
| } else { | |
| if (height > MAX_HEIGHT) { | |
| width *= MAX_HEIGHT / height; | |
| height = MAX_HEIGHT; | |
| } | |
| } | |
| canvas.width = width; | |
| canvas.height = height; | |
| var ctx = canvas.getContext('2d'); | |
| ctx.drawImage(img, 0, 0, width, height); | |
| return canvas.toDataURL(); | |
| } | |
| $scope.submitImageSelection = function () { | |
| // when the user finally selects the image they want, and clicks submit, we run this fn | |
| var imgFile = $scope.acqImageFile; | |
| convertToBase64(imgFile, function (err, data) { | |
| if (err) { | |
| /// handle error | |
| return; | |
| } | |
| // resize the image like a boss | |
| data = resizeImage(data); | |
| // finally we can send the data to a server as | |
| // just another field in a JSON payload | |
| SomeService.sendDataToServer(data, function(err){ | |
| // voila | |
| }); | |
| }); | |
| }; | |
| // note that to display the image selection back to the user before they choose their final selection, you may want to convert to | |
| // base64 each time they change selections. | |
| // to display the image, you can use ng-src: | |
| // <img class="overlay-image" ng-src="{{acqImageData ? acqImageData : '/assets/img/placeholder.png'}}"> | |
| // <the end> | |
and how to make unit tests for this function ?
Hello, it wasn't work for me, so i change somethings:
function
resizeImage:function resizeImage(base64Str, maxWidth = 400, maxHeight = 350) { return new Promise((resolve) => { let img = new Image() img.src = base64Str img.onload = () => { let canvas = document.createElement('canvas') const MAX_WIDTH = maxWidth const MAX_HEIGHT = maxHeight let width = img.width let height = img.height if (width > height) { if (width > MAX_WIDTH) { height *= MAX_WIDTH / width width = MAX_WIDTH } } else { if (height > MAX_HEIGHT) { width *= MAX_HEIGHT / height height = MAX_HEIGHT } } canvas.width = width canvas.height = height let ctx = canvas.getContext('2d') ctx.drawImage(img, 0, 0, width, height) resolve(canvas.toDataURL()) } }) }Usage:
resizeImage(e.target.result, 1000, 1000).then((result) => { console.log(result); });Thanks for the code
Except this doesn't make the file size smaller, correct? Because it is still a string regardless of the image dimensions? I'm working with base64 but the page loads so slowly and I see a loooong string loading.
It does make the file size smaller because a smaller dimensioned image means less pixels. If you want to further reduce file size, use canvas.toDataURL('image/jpeg', 0.8) instead of just canvas.toDataURL(), since by default it saves it as a PNG with max quality. Using JPEG format at 80% quality is hardly noticeable in terms of image appearance, but the image size is much much smaller.
This is awesome, thanks!
amazing, thanks!
@gs-nasc That is acceptable. I've done a few myself and got slightly better results by passing the native type and
1totoDataUrlmethod (canvas.toDataURL('image/png', 1).