使用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,大大減少了對伺服器端上傳的壓力。
以上就是對圖片壓縮的小小見解。