圖片實(shí)現(xiàn)功能分瀏覽器實(shí)現(xiàn)
這次主要要寫如何通過右鍵粘貼獲得截圖(沒錯(cuò),就是QQ截圖)以及網(wǎng)絡(luò)圖片
chrome
$("body").on('paste','.emoji-wysiwyg-editor',function(event){
var clipboardData = (event.clipboardData || event.originalEvent.clipboardData);
//chrome提供了直接獲取剪切板上內(nèi)容的API,有的chrome瀏覽器是event.clipboardData,有的則是event.originalEvent.clipboardData
if ( clipboardData.items ) {
var items = clipboardData.items,
len = items.length,
//如果粘貼純文本,那么len=1,如果粘貼網(wǎng)頁圖片,len=2, items[0].type = 'text/plain', items[1].type = 'image/*'
//如果使用截圖工具粘貼圖片铭污,len=1, items[0].type = 'image/png'
blob = null;
for (var i = 0; i < len; i++) {
console.log(items[i]);
console.log( items[i].type);
if (items[i].type.indexOf("image") !== -1) {
event.preventDefault();
blob = items[i].getAsFile();
//blob就是需要上傳到服務(wù)器的內(nèi)容
}
}
console.log(blob);
if ( blob !== null ) {
var reader = new FileReader();
reader.onload = function (event) {
//文件讀取成功完成時(shí)觸發(fā)
// event.target.result 即為圖片的Base64編碼字符串
var base64_str = event.target.result;
//console.log(base64_str);
//根據(jù)后端服務(wù)器來選擇上傳base64的編碼或者直接上傳blob對象
doUpload(blob);
}
reader.readAsDataURL(blob);
//該方法將文件讀取為一段以 data: 開頭的字符串株婴,這段字符串的實(shí)質(zhì)就是 Data URL肯腕,Data URL是一種將小文件直接嵌入文檔的方案朗涩。這里的小文件通常是指圖像與 html 等格式的文件取视。
}
}
})
//ajax
function doUpload(file) {
$(".pg-wrapper").show();
var file = file;
//獲取img的后綴,png鬼雀、jpg等
console.log(file.type);
var form = new FormData();
form.append("file", file);
form.append("filetype",file.type);
console.log(form);
$.ajax({
url: "/uploadImg",
type: "POST",
data: form,
async: true,
processData: false,
contentType: false,
success: function(result) {
$.Insertimage(result.data);
//圖片上傳到服務(wù)器后臺(tái)成功后返回圖片的地址,Insetimage用于插入圖片
}
});
//$.Insertimage補(bǔ)充于jquery-emojirea.js這個(gè)閉包函數(shù)中
$.Insertimage= function (url) {
if (CONST.hasFocus) {
CONST.selection = util.saveSelection();
//CONST指向EmojiArea_WYSIWYG(上一篇文章提過,這個(gè)函數(shù)寫在jquery-emojirea.js這個(gè)閉包函數(shù)中)
//如果文本編輯框div被處于focus狀態(tài),則調(diào)用 util.saveSelection()函數(shù)獲取當(dāng)前光標(biāo)對象并復(fù)制給CONST.selection
}
var $img = $(EmojiArea.createImage(url));
//將url包裝成為<img src=url>的格式
if ($img[0].attachEvent) {
$img[0].attachEvent('onresizestart', function(e) { e.returnValue = false; }, false);
}
console.dir(CONST.$editor+"這里是const");
CONST.$editor.trigger('focus');
if (CONST.selection) {
util.restoreSelection(CONST.selection);
//將文本編輯框的selection(也可以是歷史記錄)存入util中,設(shè)置當(dāng)前selection為CONST.selection
}
try { util.replaceSelection($img[0]); } catch (e) {}
//對光標(biāo)部分進(jìn)行替換
CONST.onChange();
//onChange方法用于將div的內(nèi)容賦值給對應(yīng)的textarea中
}
}
對應(yīng)后臺(tái)程序
后臺(tái)用的是Node.js以及express
var formidable = require('formidable');
var fs = require('fs');
router.post('/uploadImg', function(req, res, next) {
var io = global.io;
//var io = require('socket.io').listen(server);global.io = io;,io是全局變量
var form = new formidable.IncomingForm();
var path = "";
var fields = [];
form.encoding = 'utf-8';
form.uploadDir = "upload";
form.keepExtensions = true;
form.maxFieldsSize = 30000 * 1024 * 1024;
var uploadprogress = 0;
//console.log("start:upload----"+uploadprogress);
form.parse(req);
form.on('field', function(field, value) {
fields[field] = value;
//主要用于存儲(chǔ)filetype
})
.on('file', function(field, file) {
path = '\\' + file.path;
if(fields['filetype'].match(/image/)){
var str = fields['filetype'].match(/[^image\/]\w+$/);//提取image/后面部分的圖片后綴
var str = str[0];
var reg = new RegExp(str);
if(!file.path.match(reg)){
//如果file的路徑不含圖片后綴則執(zhí)行以下操作
fs.rename(file.path,file.path+'.'+str, function(err){
if(err){
throw err;
}
console.log('done!');
path = '\\' + file.path+'.'+str;
})
}else{
path = '\\' + file.path;
}
}else{
path = '\\' + file.path;
}
})
.on('progress', function(bytesReceived, bytesExpected) {
uploadprogress = (bytesReceived / bytesExpected * 100).toFixed(0);
//console.log("upload----"+ uploadprogress);
io.sockets.in('sessionId').emit('uploadProgress', uploadprogress);
})
.on('end', function() {
//console.log('-> upload done\n');
entries.code = 0;
if(fields['filetype'].match(/image/)){
var str = fields['filetype'].match(/[^image\/]\w+$/);
var str = str[0];
var reg = new RegExp(str);
if(!path.match(reg)){
path = path + '.' + str;
}
}//再次檢查path是否正確(其實(shí)上面一段檢查并沒有什么卵用)
entries.data = path;
res.writeHead(200, {
'content-type': 'text/json'
});
res.end(JSON.stringify(entries));//將圖片地址作為json數(shù)據(jù)傳送到前臺(tái)
})
.on("err",function(err){
var callback="<script>alert('"+err+"');</script>";
res.end(callback);//這段文本發(fā)回前端就會(huì)被同名的函數(shù)執(zhí)行
}).on("abort",function(){
var callback="<script>alert('"+ttt+"');</script>";
res.end(callback);
});
});
firefox
$("body").on('paste','.emoji-wysiwyg-editor',function(event){
setTimeout(function () {
//設(shè)置setTimeout的原因是為了保證圖片先插入到div里乔遮,然后去獲取值
$(".emoji-wysiwyg-editor img").each(function () {
if($(this).attr("src").toString().match(/base64/)){//火狐瀏覽器不提供獲取clipboard內(nèi)容的api,但是允許粘貼圖片到可編輯的div中,粘貼后的圖片的src是base64編碼的形式,可將其上傳到服務(wù)器
var base64_str = $(this).attr("src");
doUploadFF(base64_str);
}else if($(this).attr("alt")===undefined||!$(this).attr("alt").toString().match(/^:.+:$/))
{
var base64_str = $(this).attr("src");
doUploadFF(base64_str);
}
//兩個(gè)if語句第一個(gè)用于獲取截圖的到的本地圖片,第二個(gè)用于獲取網(wǎng)頁上的圖片復(fù)制過來的,貌似沒差
})
}, 1);
})
//ajax
function doUploadFF(base64_str) {
console.log(base64_str);
$.ajax({
url: "/uploadImgFF",
type: "POST",
data:JSON.stringify({
'base64':base64_str,
}),
async: true,
processData: false,
contentType:"application/json",
success: function(result) {
console.log(result.store_path);
//$.Insetimage(result.data);
$(".emoji-wysiwyg-editor img").each(function () {
if($(this).attr("src").toString().match(/base64/)){
$(this).attr({src:result.store_path,alt:":"+result.store_path+":"});
$(this).addClass("Notemoji");
$.constChange();
}else if($(this).attr("alt")===undefined||!$(this).attr("alt").toString().match(/^:.+:$/))
{
$(this).attr({src:result.store_path,alt:":"+result.store_path+":"});
$(this).addClass("Notemoji");
$.constChange();
}
})
}
});
}
后臺(tái)
router.post('/uploadImgFF',function (req,res,next) {
//1.獲取客戶端傳來的src_str字符串=>判斷是base64還是普通地址=>獲取圖片類型后綴(jpg/png etc)
//=>如果是base64替換掉"前綴"("data:image\/png;base64," etc)
//2.base64 轉(zhuǎn)為 buffer對象 普通地址則先down下來
//3.寫入硬盤(后續(xù)可以將地址存入數(shù)據(jù)庫)
//4.返回picture地址
var src_str = req.body.base64,
timestamp = new Date().getTime();
console.log(src_str);
if ( src_str.match(/^data:image\/png;base64,|^data:image\/jpg;base64,|^data:image\/jpg;base64,|^data:image\/bmp;base64,/) ) {
//處理截圖 src_str為base64字符串
var pic_suffix = src_str.split(';',1)[0].split('/',2)[1],
base64 = src_str.replace(/^data:image\/png;base64,|^data:image\/jpg;base64,|^data:image\/jpg;base64,|^data:image\/bmp;base64,/, ''),
buf = new Buffer(base64, 'base64'),
store_path = './upload/' + timestamp + '.' + pic_suffix;
console.log(store_path);
fs.writeFile(store_path, buf, function (err) {
if (err) {
throw err;
} else {
res.json({'store_path': store_path});
}
});
} else {
console.log("網(wǎng)頁圖片"+src_str);
var temp_array = src_str.split('.'),
pic_suffix = temp_array[temp_array.length - 1],
store_path = './upload/' + timestamp + '.' + pic_suffix,
wstream = fs.createWriteStream(store_path);
console.log(store_path);
request(src_str).pipe(wstream);
wstream.on('finish', function (err) {
console.log("進(jìn)入finish");
if( err ) {
throw err;
} else {
res.json({'store_path': store_path});
}
});
}
})