首页 > 技术文章 > markown编辑器截图粘贴预览,并将图片传至七牛云

smartXiang 2017-03-17 00:04 原文

最近在做一个项目,需要实现类似QQ截图后,就是能够在富文本编辑器中粘贴截图并预览。

先看一下效果:

分析一下实现步骤:

  1. QQ截图后在编辑器中粘贴,肯定会有一个粘贴事件,即 paste 事件
  2. 在事件回调函数中对前端进行图片的一次压缩
  3. 前端压缩多是使用canvas,返回的是base64,这里我使用了一个 localResizeIMG.js的插件
  4. 将生成好的base64传给后台,后台可以进行图片的第二次压缩,但是感觉没必要
  5. 后台先得到七牛云的upToken,即一个上传的凭证,然后执行七牛sdk提供的上传函数

接下来,一步步的来实现:

浏览器paste事件

这个paste事件的兼容性不是很好,但是可以对用户做友好提示,如果不能使用剪切板事件的话,就在dialog中上传图片也是可以的。

当QQ截图之后,在富文本编辑器中右键黏贴或者CTRL V就会触发这个事件,这个事件有一个clipboardData属性,

这里面就是跟paste有关的数据了。详细知识可以看这一篇博文http://m.jb51.net/show/80657

我就直接复制粘贴一把梭了,>_>)

function paste(event) {
    var clipboardData = event.clipboardData;
    var items, item, types;
    if (clipboardData) {
        items = clipboardD
        a//ta.items;
        if (!items) {
            return;
        }
        // 保存在剪贴板中的数据类型
        types = clipboardData.types || [];
        for (var i = 0; i < types.length; i++) {
            if (types[i] === 'Files') {
                item = items[i];
                break;
            }
        }
        // 判断是否为图片数据
        if (item && item.kind === 'file' && item.type.match(/^image\//i)) {
            // 读取该图片
            var file = item.getAsFile(),
                reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onload = function () {
                var image = reader.result;
            }
        }
    }
}

//绑定事件
$('#editormd').on('paste', paste);

localResizeIMG.js的使用

这是一个前端压缩的插件,项目地址是https://github.com/think2011/localResizeIMG
兼容IE10以上,所以还得做个IE版本判断,然后看自己是否需要使用干这个插件,我这里就不写IE的判断了。

使用方法也很简单,lrz方法接受一个文件路径或者base64的图片,可以设置一个压缩宽度的对象,低于这个宽度的图片不会压缩,大于这个宽度的就会压缩,然后在then方法中取得压缩后的图片:

得先引入这个插件,可以使用src引入,也支持amd or cmd模块化

<script src="./dist/lrz.bundle.js"></script>

接着开始使用:

//image就是经过paste事件后得到的图片
lrz(image, {width: 1080}).then(function (res) {
    var base64 = res.base64;
}

七牛云sdk

七牛云注册好像就送10G的云储存,需要的可以去注册,先下载七牛云sdk,我使用的是php,地址https://developer.qiniu.com/kodo/sdk/php
配置这个上传的文件也很简单。将下载后的压缩包解压,删掉一下没用的文件,然后拖到项目中

uploadImageToQiliu.php:

<?php
require_once __DIR__ . '/../autoload.php';

use Qiniu\Auth;

// 引入上传类
use Qiniu\Storage\UploadManager;

$accessKey = '你的accessKey';
$secretKey = '你的secretKey';

// 初始化签权对象。
$auth = new Auth($accessKey, $secretKey);

$bucket = "空间名字";

$upToken = $auth->uploadToken($bucket);

// 初始化 UploadManager 对象并进行文件的上传。
$uploadMgr = new UploadManager();

$key = $_POST['name'];
$filePath = $_POST['image'];


list($ret, $err) = $uploadMgr->putFile($upToken, $key, $filePath);

if ($err !== null) {
    echo json_encode($err);
} else {
    echo json_encode($ret);
}

accessKeysecretKey注册后就可以看到,bucket是云储存空间名字,下图的nuc-web-images

接下来是前台传图片和图片名给后台,图片名我就直接用 new Date().getTime()

$.ajax({
    url: './apis/qiniu-sdk/myApis/uploadImageToQiliu.php',
    type: 'post',
    data: {
        "image": res.base64,
        "name": new Date().getTime()
    },
    contentType: 'application/x-www-form-urlencoded;charest=UTF-8',
    success: function (data) {
        var imageName;
        try {
            imageName = JSON.parse(data).key;
        } catch (e) {
            alert(e.toString);
        }

        var qiniuUrl = '![](http://omwtgu970.bkt.clouddn.com/' + imageName + ')';

        testEditor.insertValue(qiniuUrl);
    }
})

testEditor 是我使用的markdown编辑器的对象实例,testEditor.insertValue(qiniuUrl);就是把格式化好的markdown语句插到光标处。

整个前端代码如下:

function paste(event) {
    var clipboardData = event.clipboardData;
    var items, item, types;
    if (clipboardData) {
        items = clipboardData.items;
        if (!items) {
            return;
        }
        // 保存在剪贴板中的数据类型
        types = clipboardData.types || [];
        for (var i = 0; i < types.length; i++) {
            if (types[i] === 'Files') {
                item = items[i];
                break;
            }
        }
        // 判断是否为图片数据
        if (item && item.kind === 'file' && item.type.match(/^image\//i)) {
            // 读取该图片
            var file = item.getAsFile(),
                reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onload = function () {
                //前端压缩
                lrz(reader.result, {width: 1080}).then(function (res) {
                    $.ajax({
                        url: './apis/qiniu-sdk/myApis/uploadImageToQiliu.php',
                        type: 'post',
                        data: {
                            "image": res.base64,
                            "name": new Date().getTime()
                        },
                        contentType: 'application/x-www-form-urlencoded;charest=UTF-8',
                        success: function (data) {
                            var imageName;
                            try {
                                imageName = JSON.parse(data).key;
                            } catch (e) {
                                alert(e.toString);
                            }

                            var qiniuUrl = '![](http://omwtgu970.bkt.clouddn.com/' + imageName + ')';

                            testEditor.insertValue(qiniuUrl);
                        }
                    })
                });
            }
        }
    }
}

$('#editormd').on('paste', paste);

另外这个markdown编辑器也是开源的,项目地址是:https://github.com/pandao/editor.md

推荐阅读