看板 Knuckles_note
作者 標題 [JS] 單鍵上傳圖片 上傳前使用canvas縮圖
時間 2015年02月15日 Sun. AM 07:04:53
點一個按鈕選好檔案就開始上傳圖片
並且限制圖檔大小,太大會縮小後再上傳
範例頁: http://knuckles.disp.cc/test/imgur/imgUpload.php
在網頁上使用表單上傳圖片時:
<form id="uploadForm" name="uploadForm" action="imgur_upload_multiple.php" enctype="multipart/form-data" method="POST">
<input type="file" id="uploadInput" name="fileData[]" size="35" accept="image/*" multiple />
<input type="submit" name="submit" value="上傳"/>
</form>
<input type="file" id="uploadInput" name="fileData[]" size="35" accept="image/*" multiple />
<input type="submit" name="submit" value="上傳"/>
</form>
結果像這樣:
![[圖]](http://i.imgur.com/POxl0il.png)
要先點「選擇檔案」後,還要再點「上傳」,圖片才會上傳
如果想要選擇檔案後,就直接開始上傳的話
可以只放一個 type="file" 的 input
<div class="oneClickUpload">
<input type="file" name="fileData[]" size="35" accept="image/*" multiple />
</div>
<input type="file" name="fileData[]" size="35" accept="image/*" multiple />
</div>
然後在 Javascript 利用 input 的 onChange 事件來執行上傳圖片
<script type="text/javascript">
//前面要先載入 jQuery
$(function(){
});
function imgFileUpload(file,options){ ... } //上傳圖片的程式,寫在後面
</script>
//前面要先載入 jQuery
$(function(){
$('.oneClickUpload > input').on('click',function(){
this.value = null;
}).on('change',function(){
var files = this.files;
var i, file;
for(i=0; i<files.length; i++){
file = files[i];
if(!file.type.match(/^image/)){ //去除非圖片檔
console.log('file '+(i+1)+' is not an image');
continue;
}
//將 file 上傳,取得圖片網址
imgFileUpload(file, {
action: 'imgur_upload_base64.php',
onSubmit: function(){
//選好檔案後要做的事
},
onComplete: function(responseJSON){
//上傳完成後要做的事
}
});
}
});
});
function imgFileUpload(file,options){ ... } //上傳圖片的程式,寫在後面
</script>
如果想要自訂上傳按鈕的樣式的話
可以產生一個自訂的按鈕,然後再把隱形的 input 放在上面
例如:
單鍵上傳:
<div class="oneClickUpload">
<input type="file" name="fileData[]" size="35" multiple />
<div class="oneClickUpload-inner">上傳圖片</div>
</div>
<style type="text/css">
.oneClickUpload{
}
.oneClickUpload > input {
}
.oneClickUpload-inner{
}
</style>
<input type="file" name="fileData[]" size="35" multiple />
<div class="oneClickUpload-inner">上傳圖片</div>
</div>
<style type="text/css">
.oneClickUpload{
display: inline-block; width:70px; height: 26px; cursor: pointer;
background-color: red; font-size: 16px;
border: 1px solid black; border-color: rgba(0,0,0,0.25);
-webkit-border-radius: 0.25em; -moz-border-radius: 0.25em; border-radius: 0.25em;
}
.oneClickUpload > input {
opacity: 0; font-size: 0; cursor: pointer;
position: absolute; width: 70px; height: 26px;
}
.oneClickUpload-inner{
padding: 3px; text-align: center; vertical-align: middle;
}
</style>
將 input 設為 opacity: 0; font-size: 0;
並將大小與位置設成剛好可以覆蓋住自訂的按鈕即可
結果會像這樣:
![[圖]](http://i.imgur.com/vzLhIco.png)
接著將 input 讀到的 file 傳給 function imgFileUpload() 來上傳圖片
可設定寬度與高度的上限,若上傳的圖片太大時先會縮小後再上傳
參考: http://hacks.mozilla.org/2011/01/how-to-develop-a-html5-image-uploader/
加上一個textarea用來接收回傳的圖片網址
上傳圖片的網址:
<textarea id="upload-result"></textarea>
<textarea id="upload-result"></textarea>
選好擋案時會先在 textarea 插入字串 [img {id} uploading...]
其中 id 為 imgFileUpload 中隨機產生的字串,用來辨別不同的上傳檔案
等上傳成功後再將這個字串改為回傳的圖片網址
修改 imgFileUpload 輸入的 onSubmit 和 onComplete 為
var uploadResult = document.getElementById('upload-result');
imgFileUpload(file, {
action: 'imgur_upload_base64.php',
onSubmit: function(id){ //選好檔案後要做的事
var anchor_str = "[img "+id+" uploading...]\n";
uploadResult.value += anchor_str;
},
onComplete: function(responseJSON,id){ //上傳完成後要做的事
var data = responseJSON.data;
if(!responseJSON.success){ alert(data.error); }
var anchor_str = "[img "+id+" uploading...]\n";
var bbcode = '[img='+data.width+'x'+data.height+']'+data.link+"[/img]\n";
uploadResult.value = uploadResult.value.replace(anchor_str,bbcode);
}
});用來上傳圖片的 function imgFileUpload() 程式碼:
<script type="text/javascript">
function imgFileUpload(file, options){
}
</script>
function imgFileUpload(file, options){
$.extend({ //options 預設值
action: 'imgur_upload_base64.php', //上傳圖片的網址
maxWidth: 1000, //寬度預設最大1000px
maxHeight:0, //高度預設無限制
onSubmit: function(){}, //選好檔案時要做的事
onComplete: function(){}//上傳完成後要做的事
}, options);
var type = file.type;
var src = window.URL.createObjectURL(file);
//隨機產生一個id,用來辨別不同的上傳檔案
var id = Math.random().toString(36).substring(3,7);
options.onSubmit(id);
var img = document.createElement("img");
img.src = src;
img.onload = function(){
var width = this.width,
height = this.height,
maxWidth = options.maxWidth,
maxHeight = options.maxHeight;
//寬或高大於設定的上限時,等比例縮小到符合上限
if(width > height){
if(maxWidth>0 && width>maxWidth){
height *= maxWidth / width;
width = maxWidth;
}
}else{
if(maxHeight>0 && height>maxHeight){
width *= maxHeight / height;
height = maxHeight;
}
}
//使用縮小後的寬高建立一個canvas
var canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, width, height);
//將canvas轉為圖片的base64編碼
var dataurl = canvas.toDataURL(type);
//去掉 dataurl 開頭的 data:image/png;base64,
var regex = new RegExp('^data:'+type+';base64,');
var base64 = dataurl.replace(regex,'');
//將圖片的base64編碼上傳至網站,將回傳的JSON傳至onComplete
$.post(options.action, {base64:base64}, function(responseText){
if(!responseText.match(/^[\{\[]/)){ alert(responseText); return; }
var responseJSON = JSON.parse(responseText);
options.onComplete(responseJSON,id);
},'text');
};
}
</script>
其中使用了 canvas 來縮小圖片大小
然後將 canvas 轉為圖片的 base64 編碼
最後將 base64 傳給網站的 imgur_upload_base64.php
<?php // imgur_upload_base64.php
$image_base64 = isset($_POST['base64'])? $_POST['base64'] : '';
if(!$image_base64){ die('base64 error'); }
$imgur_result = imgur_upload($image_base64);
echo $imgur_result;
//利用 Imgur API 上傳圖片的程式,請參考 http://disp.cc/b/11-8qWb
function imgur_upload(){ ... }
$image_base64 = isset($_POST['base64'])? $_POST['base64'] : '';
if(!$image_base64){ die('base64 error'); }
$imgur_result = imgur_upload($image_base64);
echo $imgur_result;
//利用 Imgur API 上傳圖片的程式,請參考 http://disp.cc/b/11-8qWb
function imgur_upload(){ ... }
改寫成 jQuery plugin 可參考: http://disp.cc/b/11-8uGt
--
※ 作者: Knuckles 時間: 2015-02-15 07:04:53
※ 編輯: Knuckles 時間: 2015-10-23 05:43:36
※ 同主題文章:
● 02-15 07:04 □ [JS] 單鍵上傳圖片 上傳前使用canvas縮圖
02-17 10:15 □ [JS] 單鍵縮圖上傳圖片 imgUpload - jQuery Plugin
※ 看板: KnucklesNote 文章推薦值: 0 目前人氣: 0 累積人氣: 4672
回列表(←)
分享