1. 程式人生 > >使用JS壓縮使用者上傳圖片

使用JS壓縮使用者上傳圖片

程式碼Demo參考
對於圖片壓縮就我個人而言只是概念性問題。當然知識點就在那。
- 原始碼分析
- HTML5的FileReader介面
- canvas drawImage介面
- toDataUrl介面轉換base64編碼
- PHP將base64轉換成圖片
- 個人注意的點點滴滴

原始碼分析

先貼上原始碼,其他的不多說:

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="Content-Type" content
="text/html; charset=utf-8"/>
<title>圖片壓縮</title> </head> <style type="text/css"> input { margin: 10px 0; } textarea { width: 100%; height: 300px; } </style> <body> <!-- 這裡不使用enctype="multipart/form-data"的含義是禁止檔案上傳成功--> <form id="myForm" action
="__URL__/addChk" method="post">
<input type="file" value="image" id="img_input" name="image" /> <textarea id="result"></textarea> <p id="img_area"></p> <input type="hidden" name=""> <input type="button" value="上傳" onclick="replace()"
>
</form> </body> </html> <!--JS部分--> <script type="text/javascript"> var input = document.getElementById("img_input"); var result = document.getElementById("result"); var img_area = document.getElementById("img_area"); window.onload = function() { //檢測瀏覽器是否支援FileReader物件 if (typeof(FileReader) === 'undefined') { result.innerHTML = "FileReader is not supported..."; input.setAttribute('disabled', 'disabled'); } else { input.addEventListener('change', readFile, false); } }; //借鑑地址:http://www.th7.cn/web/html-css/201407/48937.shtml function readFile() { var file = this.files[0]; if (!/image\/\w+/.test(file.type)) { alert("image only please."); return false; } var reader = new FileReader();//讀取使用者上傳的圖片 reader.readAsDataURL(file);//readAsDataURL可以獲取API非同步讀取檔案資料另存為資料URL;將該URL繫結到img標籤的src屬性上,可以實現圖片上傳預覽 reader.onload = function(e) { var img = new Image, width = 640, //影象調整 quality = 0.7, //圖片質量 canvas = document.createElement("canvas"), drawer = canvas.getContext("2d"); img.src = this.result;//這句不好理解 console.log(this.result); img.onload = function() { canvas.width = width; canvas.height = width * (img.height / img.width); drawer.drawImage(img, 0, 0, canvas.width, canvas.height);//使用canvas drawInmage介面繪製canvas 2d中 img.src = canvas.toDataURL("image/jpeg", quality);//toDataUrl介面把圖片轉成base64編碼字串 console.log(img.src); result.innerHTML = '<img src="' + "data:image/png;base64,"+img.src + '" alt=""/>'; img_area.innerHTML = '<div class="sitetip">preview:</div><img src="' + img.src + '" alt="" id="generate" value="generate" /><input type="hidden" id="hide" name="hide" value="'+ img.src+'" />'; } } } function replace(){ document.getElementById('myForm').submit(); } </script> <!--JS部分-->

view.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>show</title>
</head>
<body>
恭喜你上傳成功!<br/>
圖片預覽:<br/>
<img src="__ROOT__/{$path}">
</body>
</html>

php:
注意:這裡使用的是thinkphp3.2.3,為啥用框架呢,方便開發

<?php
namespace Home\Controller;
use Think\Controller;

class IndexController extends Controller {
    public function index(){
        $this->display();
    }

    public function addChk(){
        $base_img =I('post.hide');
//$base_img是獲取到前端傳遞的src裡面的值,也就是我們的資料流檔案,哎:注意base64編碼的頭部部分
          $base_img = str_replace('data:image/jpeg;base64,', '', $base_img);
//  設定檔案路徑和檔案字首名稱
        $path = "./";
        $prefix='nx_';
        $output_file = $prefix.time().rand(100,999).'.jpg';
        $path = $path.$output_file;
//這句程式碼前加上清除輸出,防止檔案寫入錯誤
     ob_clean();
//建立將資料流檔案寫入我們建立的檔案內容中
        $ifp = fopen( $path, "wb" );
        fwrite( $ifp, base64_decode( $base_img) );
        $this->assign('path',$path);
        $this->assign('filename',$output_file);
        $this->display('show');
   }
}

HTML5的FileReader介面

借鑑
FileReader 物件允許Web應用程式非同步讀取儲存在使用者計算機上的檔案(或原始資料緩衝區)的內容,使用 File 或 Blob 物件指定要讀取的檔案或資料。
當然那麼多API我才不想多說,只要能看懂程式碼,其他有空再說。

canvas drawImage介面

借鑑
drawImage() 方法在畫布上繪製圖像、畫布或視訊。
drawImage() 方法也能夠繪製圖像的某些部分,以及/或者增加或減少影象的尺寸。當然我還是不細說。

toDataUrl介面轉換base64編碼

借鑑
怎麼理解呢?toDataUrl介面可以將圖片轉換成base64編碼。也就是將圖片轉換成字元。

PHP將base64編碼轉換成圖片

借鑑
PHP內建的base64_decode方法可以將base64編碼轉換成圖片,這一特性很大程度上對我們圖片進行上傳有了很大幫助。

個人注意的點點滴滴

就個人而言,需注意以下幾點:

上傳檔案大小限制

PHP預設對上傳檔案有很多限制,比入上傳的檔案大小必須小於2M,當然我們可以進行一些設定的修改:
開啟php.ini,首先找到
file_uploads = on;是否允許通過HTTP上傳檔案的開關。預設為ON即是開
upload_tmp_dir;檔案上傳至伺服器上儲存臨時檔案的地方,如果沒指定就會用系統預設的臨時資料夾
upload_max_filesize = 8m;望文生意,即允許上傳檔案大小的最大值。預設為2M
post_max_size = 8m ;指通過表單POST給PHP的所能接收的最大值,包括表單裡的所有值。預設為8M
一般地,設定好上述四個引數後,上傳<=8M的檔案是不成問題,在網路正常的情況下。
但如果要上傳>8M的大體積檔案,只設置上述四項還一定能行的通。

進一步配置以下的引數
max_execution_time = 600;每個PHP頁面執行的最大時間值(秒),預設30秒
max_input_time = 600 ;每個PHP頁面接收資料所需的最大時間,預設60秒
memory_limit = 8m ;每個PHP頁面所吃掉的最大記憶體,預設8M
把上述引數修改後,在網路所允許的正常情況下,就可以上傳大體積檔案了

max_execution_time = 600
max_input_time = 600
memory_limit = 32m
file_uploads = on
upload_tmp_dir = /tmp
upload_max_filesize = 32m
post_max_size = 32m

進行了這些設定後,上傳大檔案再也不用愁了。

除去base64編碼的預設頭部

記得想儲存圖片的時候,記得除去base64編碼裡面的圖片頭部,當然還需要在意的是:細節很重要
data:image/jpeg;base64,data:image/jpg;base64,一個字母弄了多久,你自己知道就好了。無論如何,好好學習技術肯定沒錯。

$base_img = str_replace('data:image/jpeg;base64,', '', $base_img);

結果:成效還是很明顯的,將4747KB的圖片壓縮成了114KB,大大減少了對伺服器端上傳的壓力。
以上就是對圖片壓縮的小小見解。