移動h5開發避免不了上傳圖片,一般我們使用html自帶的控件input
或者使用微信上傳API
。但微信上傳API不是任何地方都可以使用的,使用html自帶的控件input上傳又免不了圖片體積太大,上傳不穩定。localResizeIMG4就是為此而生的。
兼容IOS,Android,PC、自動按需加載文件
支持壓縮比例
支持原生JS、jQuery/Zepto
支持Promise特性
使用Base64
前端本地客戶端壓縮圖片,兼容IOS,Android,PC、自動按需加載文件
https://github.com/think2011/localResizeIMG
<script src="./dist/lrz.bundle.js"></script>
html
<input type="file" capture="camera" accept="image/*" name="logo" id="file">
capture="camera"
可以出現拍照;
accept="image/*"
僅接受圖片
通過change
事件可以得到用戶選擇的圖片。
document.querySelector('input').addEventListener('change', function () {
// this.files[0] 是用戶選擇的文件
lrz(this.files[0], {width: 1024})
.then(function (rst) {
// 把處理的好的圖片給用戶看看呗(可選)
var img = new Image();
img.src = rst.base64; //base64字符串
img.onload = function () {
document.body.appendChild(img);
};
return rst;
})
.then(function (rst) {
// 這裡該上傳給後端啦
/* ==================================================== */
// 原生ajax上傳代碼,所以看起來特別多,但絕對能用
// 其他框架,例如jQuery處理formData略有不同,請自行google,baidu。
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://localhost:5000/');
xhr.onload = function () {
if (xhr.status === 200) {
// 上傳成功
} else {
// 處理其他情況
}
};
xhr.onerror = function () {
// 處理錯誤
};
xhr.upload.onprogress = function (e) {
// 上傳進度
var percentComplete = ((e.loaded / e.total) || 0) * 100;
};
// 添加參數
rst.formData.append('fileLen', rst.fileLen);
rst.formData.append('xxx', '我是其他參數');
// 觸發上傳
xhr.send(rst.formData);
/* ==================================================== */
return rst;
})
.catch(function (err) {
// 萬一出錯了,這裡可以捕捉到錯誤信息
// 而且以上的then都不會執行
alert(err);
})
.always(function () {
// 不管是成功失敗,這裡都會執行
});
});
返回的rst
對象數據示例:
{origin: File, base64: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD…iigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP/Z", base64Len: 1507}
origin: File
lastModified: 1442482311173
lastModifiedDate: Thu Sep 17 2015 17:31:51 GMT+0800 (中國標准時間)
name: "upload-add.png"
size: 291
type: "image/png"
webkitRelativePath: ""
$(function(){
$('input[name=logo]').on('change', function(){
lrz(this.files[0], {width: 640})
.then(function (rst) {
$.ajax({
url: site_url + 'api/user/updLogo',
type: 'post',
data: {img: rst.base64},
dataType: 'json',
timeout: 200000,
error: doAjax.error,
success: doAjax.success,
});
})
.catch(function (err) {
})
.always(function () {
});
});
});
如果您的圖片不是來自用戶上傳的,那麼也可以直接傳入圖片路徑:
lrz('./xxx/xx/x.png')
.then(function (rst) {
// 處理成功會執行
})
.catch(function (err){
// 處理失敗會執行
})
.always(function () {
// 不管是成功失敗,都會執行
});
$base64_image_content = $_POST['img'];
if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)){
$type = $result[2]; //jpeg
$img = base64_decode(str_replace($result[1], '', $base64_image_content)); //返回文件流
}
//使用AliOSS上傳
$url = OSS::upload($img, $type);
其中$result
內容:
Array
(
[0] => data:image/jpeg;base64,
[1] => data:image/jpeg;base64,
[2] => jpeg
)
請在服務器環境(如LAMP)運行。
index.html
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>移動端使用localResizeIMG4壓縮圖片</title>
<script src="./dist/lrz.bundle.js"></script>
<script src="./dist/zepto.min.js"></script>
</head>
<body>
上傳圖片<input type="file" capture="camera" accept="image/*" name="logo" id="file">
<script>
$(function(){
$('input[name=logo]').on('change', function(){
lrz(this.files[0], {width: 640})
.then(function (rst) {
console.log(rst);
$.ajax({
url: 'upload.php',
type: 'post',
data: {img: rst.base64},
dataType: 'json',
timeout: 200000,
success: function (response) {
if (response.ecd == '0') {
alert('成功');
return true;
} else {
return alert(response.msg);
}
},
error: function (jqXHR, textStatus, errorThrown) {
if (textStatus == 'timeout') {
a_info_alert('請求超時');
return false;
}
alert(jqXHR.responseText);
}
});
})
.catch(function (err) {
})
.always(function () {
});
});
});
</script>
</body>
upload.php
<?php
$base64_image_content = $_POST['img'];
if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)){
$type = $result[2]; //jpeg
$img = base64_decode(str_replace($result[1], '', $base64_image_content)); //返回文件流
}
//var_dump($_POST); //string(1507) "data:image/jpeg;base64,/9j/4AAQSkZJR...
//var_dump($result); //"data:image/jpeg;base64," "data:image/jpeg;base64," "jpeg"
//var_dump($img); //返回的是資源,直接使用<img src="$img" />可以顯示圖片
$tmp_file = time(). '.' .$type;
file_put_contents($tmp_file, $img); //可以直接保存為本地圖片
//或者使用AliOSS上傳
//$url = OSS::upload($img, $type);
return ajaxReturn($tmp_file);
function ajaxReturn($data = array(), $code = 0, $msg = '成功'){
$result = array(
'result' => $data,
'ecd' => $code,
'msg' => $msg,
);
echo json_encode($result);
exit;
}
lrz(file, [options]);
file
通過 input:file
得到的文件,或者直接傳入圖片路徑
[options]
這個參數允許忽略width {Number}
圖片最大不超過的寬度,默認為原圖寬度,高度不設時會適應寬度。height {Number}
同上quality {Number}
圖片壓縮質量,取值 0 - 1,默認為0.7fieldName {String}
後端接收的字段名,默認:file
返回值是一個promise
對象
then(rst)
rst.formData
後端可處理的數據rst.file
壓縮後的file對象(默認已經丟在rst.formData有一份了),需要注意的是如果壓縮率太低的話,這個會是原始的file對象rst.fileLen
生成後的圖片的大小,後端可以通過此值來校驗是否傳輸完整rst.base64
生成後的圖片base64,後端可以處理此字符串為圖片,也直接用於img.src = base64rst.base64Len
生成後的base64的大小,後端可以通過此值來校驗是否傳輸完整 (如果采用base64上傳方式)rst.origin
也就是原始的file對象,裡面存了一些原始文件的信息,例如大小,日期等。
catch(err)
always()
默認的上傳按鈕不好看,而且安卓和iPhone也不一樣。需要進行統一:
原理就是使用背景圖,把input本身透明度設置為0.
<div style="background:url(images/upload-add.png) no-repeat right/40px;">
<input type="file" capture="camera" accept="image/*" name="logo" id="file" class="selectinput" style="width:100%;opacity:.01">
</div>
- php讀取和保存base64編碼的圖片內容 - fxhover的個人空間 - 開源中國社區
http://my.oschina.net/fxhover/blog/209277