简体   繁体   中英

Resize image in the client side before upload

Is there any client side script can resize automatically the image uploaded in the input file by the user, and replace automatically the old image by the new image resized in the same input ..I want to do this to send this image to my php model after.. thanks in advance for your help.

 <!DOCTYPE HTML>
 <html>
 <head>
     <title>Untitled</title>
 </head>
 <body>
    <form action="model.php" method="post" enctype="multipart/form-data">
       <input type="file" name="image"/>
       <input type="submit" name="do" value="submit"/>
    </form>
 </body>
 </html>

<?php
$target_dir = "folder/";
$filename    = $_FILES["image"]["name"];
$basename    = basename($_FILES["image"]["name"]);
$target_file = $target_dir .$basename;
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
$tmp         = $_FILES["image"]["tmp_name"];
if(move_uploaded_file($tmp,$target_file))
{
    echo'done!';
}
?>

This is how i would have solved it...

 // Used for creating a new FileList in a round-about way function FileListItem(a) { a = [].slice.call(Array.isArray(a) ? a : arguments) for (var c, b = c = a.length, d = !0; b-- && d;) d = a[b] instanceof File if (!d) throw new TypeError("expected argument to FileList is File or array of File objects") for (b = (new ClipboardEvent("")).clipboardData || new DataTransfer; c--;) b.items.add(a[c]) return b.files } fileInput.onchange = async function change() { const maxWidth = 320 const maxHeight = 240 const result = [] for (const file of this.files) { const canvas = document.createElement('canvas') const ctx = canvas.getContext('2d') const img = await file.image() // native alternetive way (don't take care of exif rotation) // https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/createImageBitmap // const img = await createImageBitmap(file) // calculate new size const ratio = Math.min(maxWidth / img.width, maxHeight / img.height) const width = img.width * ratio + .5 | 0 const height = img.height * ratio + .5 | 0 // resize the canvas to the new dimensions canvas.width = width canvas.height = height // scale & draw the image onto the canvas ctx.drawImage(img, 0, 0, width, height) // just to preview document.body.appendChild(canvas) // Get the binary (aka blob) const blob = await new Promise(rs => canvas.toBlob(rs, 1)) const resizedFile = new File([blob], file.name, file) result.push(resizedFile) } const fileList = new FileListItem(result) // temporary remove event listener since // assigning a new filelist to the input // will trigger a new change event... fileInput.onchange = null fileInput.files = fileList fileInput.onchange = change }
 <!-- screw-filereader will take care of exif rotation for u --> <script src="https://cdn.jsdelivr.net/npm/screw-filereader@1.4.3/index.min.js"></script> <form action="https://httpbin.org/post" method="post" enctype="multipart/form-data"> <input type="file" id="fileInput" name="image" accept="image/*" /> <input type="submit" name="do" value="submit" /> </form>

PS. it won't resize in stackoverflow due to iframe being more sandboxed and secure, work in jsfiddle: https://jsfiddle.net/f2oungs3/3/

You could draw the image to a resized canvas via the FileReader API and then use canvas.toDataURL('image/png') to get the base64 image to send to the server.

Here is a simplified example of resizing an image to 320x240:

 document.getElementById('example').addEventListener('change', function(e) { var canvas = document.createElement('canvas') var canvasContext = canvas.getContext('2d') canvas.setAttribute("style", 'opacity:0;position:absolute;z-index:-1;top: -100000000;left:-1000000000;width:320px;height:240px;') document.body.appendChild(canvas); var img = new Image; img.onload = function() { canvasContext.drawImage(img, 0, 0, 320, 240); var base64Image = canvas.toDataURL('image/png') console.log(base64Image) // Post to server // sendImage(base64Image) document.body.removeChild(canvas) URL.revokeObjectURL(img.src) } img.src = URL.createObjectURL(e.target.files[0]); }) function sendImage() { var data = canvas.toDataURL('image/png'); var ajax = null; if (window.XMLHttpRequest) { ajax = new XMLHttpRequest(); } else if (window.ActiveXObject) { ajax = new ActiveXObject("Microsoft.XMLHTTP"); } ajax.open('POST', 'https://example/route', true); ajax.setRequestHeader('Content-Type', 'application/octet-stream'); ajax.onreadystatechange = function() { if (ajax.readyState === XMLHttpRequest.DONE) { if (ajax.status === 200) { // Success } else { // Fail } } }; ajax.send(data); }
 <input id="example" type="file" />

And then on the server:

// or however you want to get the posted contents.
$png = isset($GLOBALS["HTTP_RAW_POST_DATA"]) ? $GLOBALS["HTTP_RAW_POST_DATA"] : file_get_contents("php://input");
if (strpos($png, 'data:image/png;base64,') === 0) {
$png = str_replace('data:image/png;base64,', '', $png);
$png = str_replace(' ', '+', $png);
$png = base64_decode($png);
}

file_put_contents($image_path, $png);

EDIT
The code now includes a way to upload the image to the server.
You could also use jQuery or the more modern fetch API to upload the image. JsFiddle available here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM