图片实现功能分浏览器实现
这次主要要写如何通过右键粘贴获得截图(没错,就是QQ截图)以及网络图片
chrome
$("body").on('paste','.emoji-wysiwyg-editor',function(event){
var clipboardData = (event.clipboardData || event.originalEvent.clipboardData);
//chrome提供了直接获取剪切板上内容的API,有的chrome浏览器是event.clipboardData,有的则是event.originalEvent.clipboardData
if ( clipboardData.items ) {
var items = clipboardData.items,
len = items.length,
//如果粘贴纯文本,那么len=1,如果粘贴网页图片,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就是需要上传到服务器的内容
}
}
console.log(blob);
if ( blob !== null ) {
var reader = new FileReader();
reader.onload = function (event) {
//文件读取成功完成时触发
// event.target.result 即为图片的Base64编码字符串
var base64_str = event.target.result;
//console.log(base64_str);
//根据后端服务器来选择上传base64的编码或者直接上传blob对象
doUpload(blob);
}
reader.readAsDataURL(blob);
//该方法将文件读取为一段以 data: 开头的字符串,这段字符串的实质就是 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);
//图片上传到服务器后台成功后返回图片的地址,Insetimage用于插入图片
}
});
//$.Insertimage补充于jquery-emojirea.js这个闭包函数中
$.Insertimage= function (url) {
if (CONST.hasFocus) {
CONST.selection = util.saveSelection();
//CONST指向EmojiArea_WYSIWYG(上一篇文章提过,这个函数写在jquery-emojirea.js这个闭包函数中)
//如果文本编辑框div被处于focus状态,则调用 util.saveSelection()函数获取当前光标对象并复制给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中,设置当前selection为CONST.selection
}
try { util.replaceSelection($img[0]); } catch (e) {}
//对光标部分进行替换
CONST.onChange();
//onChange方法用于将div的内容赋值给对应的textarea中
}
}
对应后台程序
后台用的是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;
//主要用于存储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的路径不含图片后缀则执行以下操作
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是否正确(其实上面一段检查并没有什么卵用)
entries.data = path;
res.writeHead(200, {
'content-type': 'text/json'
});
res.end(JSON.stringify(entries));//将图片地址作为json数据传送到前台
})
.on("err",function(err){
var callback="<script>alert('"+err+"');</script>";
res.end(callback);//这段文本发回前端就会被同名的函数执行
}).on("abort",function(){
var callback="<script>alert('"+ttt+"');</script>";
res.end(callback);
});
});
firefox
$("body").on('paste','.emoji-wysiwyg-editor',function(event){
setTimeout(function () {
//设置setTimeout的原因是为了保证图片先插入到div里,然后去获取值
$(".emoji-wysiwyg-editor img").each(function () {
if($(this).attr("src").toString().match(/base64/)){//火狐浏览器不提供获取clipboard内容的api,但是允许粘贴图片到可编辑的div中,粘贴后的图片的src是base64编码的形式,可将其上传到服务器
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);
}
//两个if语句第一个用于获取截图的到的本地图片,第二个用于获取网页上的图片复制过来的,貌似没差
})
}, 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();
}
})
}
});
}
后台
router.post('/uploadImgFF',function (req,res,next) {
//1.获取客户端传来的src_str字符串=>判断是base64还是普通地址=>获取图片类型后缀(jpg/png etc)
//=>如果是base64替换掉"前缀"("data:image\/png;base64," etc)
//2.base64 转为 buffer对象 普通地址则先down下来
//3.写入硬盘(后续可以将地址存入数据库)
//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("网页图片"+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("进入finish");
if( err ) {
throw err;
} else {
res.json({'store_path': store_path});
}
});
}
})