<?php if(isset($_GET['upload']) && $_GET['upload'] == 'img'){ //二進制數據流 $data = file_get_contents ( 'php://input' ); // 不須要php.ini設置,內存壓力小 if(empty($data)){ $data = gzuncompress ( $GLOBALS ['HTTP_RAW_POST_DATA'] ); // 須要php.ini設置 } if(imagecreatefromstring($data) == false){ exit('圖片已損壞'); } $filename=time().'.png'; $ret = file_put_contents($filename, $data, true); exit('http://'.$_SERVER['HTTP_HOST'].'/'.$filename); } ?> <!DOCTYPE html> <html> <head> </head> <body> <div id="main"> <h1>使用canvas在前端壓縮圖片實例頁面</h1> <div id="body"> <div id="effect" class="part"> <h3>效果(400x400限制):</h3> <div class="show"> <div class="demo"> <p><input id="file" type="file" accept="image/gif, image/png, image/jpg, image/jpeg"></p> <p id="log"></p> </div> </div> </div> </div> </div> <script> // 寫log方法,演示輔助,與主邏輯無關 var log = function (info) { document.getElementById('log').innerHTML += (info + '<br>'); }; var eleFile = document.querySelector('#file'); if (window.FormData) { // 壓縮圖片須要的一些元素和對象 var reader = new FileReader(), img = new Image(); // 選擇的文件對象 var file = null; // 縮放圖片須要的canvas var canvas = document.createElement('canvas'); var context = canvas.getContext('2d'); // base64地址圖片加載完畢後 img.onload = function () { // 圖片原始尺寸 var originWidth = this.width; var originHeight = this.height; log('圖片原尺寸是:' + [originWidth, originHeight].join('x')); // 計算出目標壓縮尺寸 var maxWidth = 400, maxHeight = 400; // 目標尺寸 var targetWidth = originWidth, targetHeight = originHeight; if (originWidth > maxWidth || originHeight > maxHeight) { // 圖片尺寸超過400x400的限制 if (originWidth / originHeight > maxWidth / maxHeight) { // 更寬,按照寬度限定尺寸 targetWidth = maxWidth; targetHeight = Math.round(maxWidth * (originHeight / originWidth)); } else { targetHeight = maxHeight; targetWidth = Math.round(maxHeight * (originWidth / originHeight)); } log('超過400x400的限制,圖片大小限制爲' + [targetWidth, targetHeight].join('x')); } else { log('圖片尺寸較小,不壓縮'); } canvas.width = targetWidth; canvas.height = targetHeight; // 清除畫布 context.clearRect(0, 0, targetWidth, targetHeight); // 圖片壓縮 context.drawImage(img, 0, 0, targetWidth, targetHeight); log('圖片blob二進制形式ajax上傳,當前進度<span id="percent"></span>'); // 轉爲blob並上傳 canvas.toBlob(function (blob) { // 圖片ajax上傳 var xhr = new XMLHttpRequest(); // 顯示進度的元素 var elePercent = document.getElementById('percent'); // 上傳文件名 var filename = encodeURIComponent(file.name).replace(/%/g, ''); // 上傳中 xhr.upload.addEventListener("progress", function(e) { elePercent.innerHTML = Math.round(100 * e.loaded / e.total) / 100 + '%'; }, false); // 文件上傳成功或是失敗 xhr.onreadystatechange = function(e) { if (xhr.readyState == 4) { if (xhr.status == 200) { // 100%進度 elePercent.innerHTML = '100%'; // 顯示上傳成功後的圖片地址 var response = xhr.responseText; if (/^http/.test(response)) { //response = response.split(filename)[0] + filename; log('圖片上傳成功,地址是:<a href="'+ response +'" target="_blank">'+ response +'</a>'); } else { log(response); } } } }; // 開始上傳 xhr.open("POST", '?upload=img', true); xhr.setRequestHeader("X_FILENAME", filename); xhr.send(blob); }, file.type || 'image/png'); }; // 文件base64化,以便獲知圖片原始尺寸 reader.onload = function(e) { // 圖片尺寸 img.src = e.target.result; }; eleFile.addEventListener('change', function (event) { file = event.target.files[0]; if (file.type.indexOf("image") == 0) { log('已選擇圖片'+ file.name +',大小爲'+ Math.round(1000 * file.size / (1024*1024)) / 1000 +'M。'); reader.readAsDataURL(file); } else { log('選擇的文件非圖片,到此爲止。'); } }); } </script> </body> </html>
效果圖(canvas壓縮圖片會失真):php
參考:html
php canvas 前端JS壓縮,獲取圖片二進制流數據並上傳前端
https://www.cnblogs.com/-mrl/p/8708114.htmlhtml5
https://www.jianshu.com/p/b7f5a706d7daajax
http://www.imwinlion.com/archives/49canvas
HTML5 file API加canvas實現圖片前端JS壓縮並上傳wordpress
http://www.zhangxinxu.com/wordpress/2017/07/html5-canvas-image-compress-upload/this