七牛雲上傳--官方JSDK與photoClip截圖Base64編碼
主要
1、php後臺生成七牛雲uploadtoken
2、前端使用官方JSDK上傳原圖
3、photoClip截圖 生成Base64圖片
4、上傳base64 編碼圖片到七牛雲
php後臺生成uploadtoken
下載php的SDK,然後引用SDK中的Auth即可:
七牛雲官方php的SDK
use Think\Controller;
use Qiniu\Auth;
use Qiniu\Storage\UploadManager;
use Org\Net\Http;
class QiniuLogic extends Controller{
public function get_token(){
$accessKey = C("QINIU_ACCESS"); //這個是七牛雲賬號的access
$secretKey = C("QINIU_SECRET"); //這個是七牛雲賬號的secret
$bucket = C("QINIU_BUCKET"); //這個是七牛雲的內容空間
vendor("Qiniu/autoload");
$auth = new Auth($accessKey, $secretKey);
$policy = array(
"scope" =>$bucket.":".$accessKey,
"insertOnly"=>0
);
$uptoken = $auth->uploadToken($bucket, null, 36000, $policy);
$this->assign("QiniuToken",$uptoken); //我們要的token,必需
$this->assign("QiniuDomain",C("QINIU_DOMAIN")); //這個是cname後的域名,非必須
}
}
前端頁面使用官方JSDK上傳原圖
首先,下載一個官方的JSDK
然後在html頁面中引用js,官方文件中引用的比較多,這裡引用兩個:plupload.full.min.js和qiniu.min.js就夠用了。
上傳過程中可能出現地域的問題:
常見問題處理
html頁面
<div>
<img id="image" src='{$gradeImg}' />
<input type="hidden" id="qiniu-uptoken" value="{$QiniuToken}">
<input type="hidden" id="qiniu-domain" value="{$QiniuDomain}">
<input type="hidden" id="image_original" value="{$gradeImg}">
</div>
<!--七牛雲直接上傳,這裡可以參考官方的文件-->
<div id="qiniu-upload-container" style="display: none;">
<button id="qiniu-upload-btn" class="btn btn-success">
上傳
</button>
<div id="fsUploadProgress">
</div>
</div>
<!--七牛雲直接上傳end-->
<!--七牛雲圖直接上傳,upload.js 是自己需要寫的,其它兩個是SDK檔案的-->
<script src="../qiniu/plupload/plupload.full.min.js"></script>
<script src="../qiniu/dist/qiniu.min.js"></script>
<script src="../qiniu/js/upload.js"></script>
<!--七牛雲圖直接上傳end-->
JavaScript-upload.js
官方文件中有很多內容,這裡做了一些簡化:
主要修改‘FileUploaded’,‘key’和 randStr() 方法
$(function () {
var uploader = Qiniu.uploader({
runtimes: 'html5,flash,html4',
browse_button: 'qiniu-upload-btn',
container: 'qiniu-upload-container',
drop_element: '',
max_file_size: '10mb',
flash_swf_url: 'bower_components/plupload/js/Moxie.swf',
dragdrop: false,
chunk_size: '2mb',
multi_selection: !(mOxie.Env.OS.toLowerCase()==="ios"),
uptoken: $('#qiniu-uptoken').val(),
domain: $('#qiniu-domain').val(),
get_new_uptoken: false,
auto_start: true,
log_level: 5,
init: {
'FilesAdded': function(up, files) {
$("#qiniu-upload-btn").html("正在上傳中...");
$("#qiniu-upload-btn").attr("disabled",true);
},
'FileUploaded': function(up, file, info) { //主要是這個方法
var res = $.parseJSON(info);
var image = $("#qiniu-domain").val()+res.key;
$("#image_original").val(image);
var thumb = image+"?imageView2/2/w/500/h/300";
$("#image").attr("src",thumb);
$("#qiniu-upload-btn").html("重新上傳");
$("#qiniu-upload-btn").attr("disabled",false);
},
'UploadProgress': function(up, file) {
},
'Error': function(up, err, errTip) {
$("#qiniu-upload-btn").html("重新上傳");
$("#qiniu-upload-btn").attr("disabled",false);
alert("上傳失敗!請重試!");
}
,
'Key': function(up, file) {//在這裡可以改變檔案的名稱和路徑
var key = "public/";
var now = new Date();
key += now.getFullYear().toString()+(now.getMonth()+1).toString()+"/"+now.getDate()+"/"+now.getHours()+"/";
key += randStr()+".png";
return key
}
}
});
uploader.bind('FileUploaded', function() {
console.log('hello man,a file is uploaded');
});
});
function randStr() {//這個是為了生成隨機字串用的
var str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
var n = 10, s = "";
for(var i = 0; i < n; i++){
var rand = Math.floor(Math.random() * str.length);
s += str.charAt(rand);
}
return s;
}
photoClip截圖 生成Base64圖片
首先下載jQueryphotoClip外掛
然後引入js檔案,編寫html佈局
最後js實現
注:js程式碼中涉及到一個彈窗外掛layer,很簡單,引用一個js就行了。
html頁面
<style>
.load_mask{ position: absolute; width: 100%; height: 100%; text-align: center; padding-top: 30%;background-color: #fffeff;z-index: 100;opacity: 0.9;display: none;}
#loadText{margin-top: 20px;font-size: 20px;}
#img_show{position: fixed;width: 100%;height: 100%;top: 0;left: 0;background-color: #0c0c0c;z-index: 100;display: none;}
#img_show .sn-operation-content{position: absolute;z-index: 99;text-align: center;width: 100%;bottom:10%;}
#img_show .btn{margin: 0 10px;}
.shunshizhen{ width: 30px; height: 30px; position: absolute; z-index: 99; color: #ffffff; line-height: 30px; font-size: 30px; left: 48%; top: 10%;}
</style>
<div class="load_mask">
<img src="../images/icon/loading.gif" alt="" class="t_loadImg">
<div id="loadText">圖片剪裁中...</div>
</div>
<div id="img_show">
<div class="sn-operation-content">
<a class="sn-photoclip-cancel btn btn-white">取消</a>
<a class="sn-photoclip-ok btn btn-danger">選取</a>
</div>
<i class="icon-repeat shunshizhen"></i>
</div>
<div>
<img id="image" src='{$gradeImg}' />
<input type="hidden" id="qiniu-uptoken" value="{$QiniuToken}">
<input type="hidden" id="qiniu-domain" value="{$QiniuDomain}">
<input type="hidden" id="image_original" value="{$gradeImg}">
</div>
<!--截圖上傳-->
<div id="mm-photoclip">
<input type="file" id="file" accept="image/*" />
<label for="file" class="btn btn-success">上傳</label>
</div>
<!--截圖上傳end-->
<script src="../common/layer/layer.min.js"></script>
<script src="../photoclip/iscroll-zoom.js"></script>
<script src="../photoclip/hammer.js"></script>
<script src="../photoclip/lrz.all.bundle.js"></script>
<script src="../photoclip/jquery.photoClip.js"></script>
<!--base64.js 和 upload_image.js 自己寫-->
<script src="../base64.js"></script>
<script src="../upload_image.js"></script>
upload_image.js
程式碼中有很詳細的註釋,就不解釋了
注:1、clipArea.shunshizhen();這個是圖片順時針的效果方法,要自己去改jquery.photoClip.js 檔案。因為這個不在文章的內容範圍,就不解釋了。
2、photoClip外掛有個相容性的問題,還是得自己去改。
3、putb64()這是一個上傳base64圖片到七牛雲的方法,後面會講。
var file_name;
$(function () {
var obj;
var clipArea = new bjj.PhotoClip("#img_show", {
size: [200, 272], // 擷取框的寬和高組成的陣列。預設值為[260,260]
adaptive: null, // 擷取框自適應,擷取框寬和高的百分比組成的陣列。預設為 null。如果設定了該引數,且值有效,則會忽略 size 的大小設定,size 中的值僅用於計算寬高比。當設定了其中一個值得百分比時,如果另一個未設定,則將會按 size 中的比例等比縮放。
outputSize: [200,272], // 輸出影象的寬和高組成的陣列。預設值為[0,0],表示輸出影象原始大小
outputType: "jpg", // 指定輸出圖片的型別,可選 "jpg" 和 "png" 兩種種類型,預設為 "jpg"
outputQuality: .8, // 輸出質量,取值 0 - 1,預設為0.8。(這個質量不是最終輸出的質量,與 lrzOption.quality 是相乘關係)
file: "#file", // 上傳圖片的<input type="file">控制元件的選擇器或者DOM物件
source: "", // 需要裁剪圖片的url地址。該引數表示當前立即開始裁剪的圖片,不需要使用 file 控制元件獲取。注意,該引數不支援跨域圖片。
view: "", // 顯示擷取後圖像的容器的選擇器或者DOM物件
ok: ".sn-photoclip-ok", // 確認截圖按鈕的選擇器或者DOM物件
loadStart: function(file) {
obj = this;
file_name = file.name;
$(".load_mask").show();
$("#loadText").html("圖片讀取中...");
}, // 開始載入的回撥函式。this指向當前 PhotoClip 的例項物件,並將正在載入的 file 物件作為引數傳入(如果是使用 source 載入圖片,則該引數為圖片的 img 物件)
loadComplete: function(img) {
$("#img_show").fadeIn(250);
$(".load_mask").hide();
$("#loadText").html("圖片裁剪中...");
$(".shunshizhen").unbind('click').bind("click",function(){
clipArea.shunshizhen();
});
}, // 載入完成的回撥函式。this指向當前 PhotoClip 的例項物件,並將圖片的 img 物件作為引數傳入
loadError: function(event) {
show_error("截圖外掛出錯");
}, // 載入失敗的回撥函式。this指向當前 PhotoClip 的例項物件,並將錯誤事件的 event 物件作為引數傳入
clipFinish: function(dataURL) {
// layerIndex1= layer.open({
// type: 2
// ,content: '圖片剪裁中'
// });
if(!navigator.onLine){
layer.alert("網路不好,請檢查網路再上傳喲~");
$("#img_show").fadeOut(250);
return false;
}
$(".load_mask").show();
putb64(dataURL); //上傳base64圖片到七牛雲
$("#img_show").fadeOut(250);
}, // 裁剪完成的回撥函式。this指向當前 PhotoClip 的例項物件,會將裁剪出的影象資料DataURL作為引數傳入
lrzOption: { // lrz壓縮外掛的配置引數
width:500, // 圖片最大不超過的寬度,預設為原圖寬度,高度不設時會適應寬度。
height: 500, // 圖片最大不超過的高度,預設為原圖高度,寬度不設時會適應高度。
quality: 1 // 圖片壓縮質量,取值 0 - 1,預設為0.7。(這個質量不是最終輸出的質量,與 outputQuality 是相乘關係)
}
});
$(".sn-photoclip-cancel").click(function() {
$("#img_show").fadeOut(250);
});
})
上傳base64 編碼圖片到七牛雲
官方有相應的說明:如何上傳base64編碼圖片到七牛雲
因為我這裡有個需求:修改KEY值,就是改變上傳檔案在七牛上的名字。
這裡說得很清楚,可以不用管uptoken.SaveKey , 直接在url後面加個欄位並且欄位要base64加密
base64.js
js給字串進行base64編譯的。網上一搜一大把:
function str2Base64(str) {
var b = new Base64();
return b.encode(str);
}
function Base64() {
// private property
_keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
// public method for encoding
this.encode = function (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = _utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
_keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
_keyStr.charAt(enc3) + _keyStr.charAt(enc4);
}
return output;
}
// public method for decoding
this.decode = function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = _keyStr.indexOf(input.charAt(i++));
enc2 = _keyStr.indexOf(input.charAt(i++));
enc3 = _keyStr.indexOf(input.charAt(i++));
enc4 = _keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = _utf8_decode(output);
return output;
}
// private method for UTF-8 encoding
_utf8_encode = function (string) {
string = string.replace(/\r\n/g,"\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
}
// private method for UTF-8 decoding
_utf8_decode = function (utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
} else {
c2 = utftext.charCodeAt(i+1);
c3 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
}
put64() 上傳base64圖片到七牛雲
和官方提供的一樣,只是修改了一下key值
方法randStr() 用於生成隨機的字串
function putb64(base){
if(!navigator.onLine){
layer.alert("網路不好,請檢查網路再上傳喲~");
$(".load_mask").hide();
return false;
}
var token = $("#qiniu-uptoken").val();
var bases = base.split(";base64,");
var pic = bases[1];
var url = "http://upload.qiniu.com/putb64/-1"; //非華東空間需要根據注意事項 1 修改上傳域名
var xhr = new XMLHttpRequest();
xhr.onreadystatechange=function(){
if (xhr.readyState==4){
var result = eval('(' + xhr.responseText + ')');
var key = result.key;
$(".load_mask").hide();
var image = $("#qiniu-domain").val()+key;
$("#image_original").val(image);
$("#image").attr("src",image);
// success_upload(key,[]);
}
};
var mm_key = "public/"+randStr()+".png";
mm_key = str2Base64(mm_key); //base64編譯
mm_key = mm_key.replace("+","-");
mm_key = mm_key.replace("/","_");
url += "/key/"+mm_key;
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/octet-stream");
xhr.setRequestHeader("Authorization", "UpToken " + token);
xhr.send(pic);
}
function randStr() {
var str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
var n = 10, s = "";
for(var i = 0; i < n; i++){
var rand = Math.floor(Math.random() * str.length);
s += str.charAt(rand);
}
return s;
}