UEditor插件开发,基于Base64编码上传图片

引用下UEditor官网的介绍,阐述下Ueditor是什么。官网地址http://ueditor.baidu.com/website/

UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点,开源基于MIT协议,允许自由使用和修改代码...

  开发背景:本程序提供给站长老婆写各种游记,及各种小清新文章。但是老婆大人总抱怨上传图片不好用,每次都要先调整小于网站限制大小后才能够上传。于是乎开发需求就是这么产生了。本来是打算用ActiveX插件来解决这个问题,但是后来发现这个方案对浏览器支持并不是特别完成。所以使用html5的Canvas来解决这个问题,现在本地使用Canvas调整上传图片的长宽,然后转换成base64使用post发送到服务器。

网站后台使用的是UEditor编辑器,框架使用了ThinkPHP,所以一并使用了专门为ThinkPHP编写的UeditorController.class.php。开源社区网址:https://github.com/Nintendov/Ueditor-thinkphp


   在Ueditor提供的例子下创建一个ueditor插件。官网文档说明:http://fex.baidu.com/ueditor/#dev-developer

   在\ueditor\third-party下创建一个文件夹,取名为uploadImage

   根据网站提供的例子,将addCustomizeDialog.js复制到文件夹下面并作如下编辑

addCustomizeDialog.js

UE.registerUI('dialog', function(editor, uiName) {
    //获取当前js文件的绝对路径
    var js = document.scripts;
    var jsPath;
    for (var i = js.length; i > 0; i--) {
        if (js[i - 1].src.indexOf("addCustomizeDialog.js") > -1) {
            jsPath = js[i - 1].src.substring(0, js[i - 1].src.lastIndexOf("/") + 1);
        }
    }
    //alert(jsPath);
    //创建dialog
    var dialog = new UE.ui.Dialog({
        //指定弹出层中页面的路径,这里只能支持页面,因为跟addCustomizeDialog.js相同目录,所以无需加路径
        iframeUrl: jsPath+'uploadPreview.html?url='+editor.ui.serverUrl,
        //需要指定当前的编辑器实例
        editor: editor,
        //指定dialog的名字
        name: uiName,
        //dialog的标题
        title: '上传图片',
        //指定dialog的外围样式
        cssRules: "width:1024px;height:520px;",

        //如果给出了buttons就代表dialog有确定和取消
        buttons: [{
            className: 'edui-okbutton',
            label: '确定',
            onclick: function() {


                
                var jsonData=$('#'+dialog.id+'_iframe').contents().find('#jsonData').html();
                if(jsonData!='')
                {
                editor.focus();
                //jsonData.substr(1,jsonData.length-1);
                //jsonData="{\"rltData\":"+jsonData+"}";
                jsonData=jQuery.parseJSON(jsonData);
                $.each(jsonData, function(index, val) {
                    editor.execCommand('insertHtml','<p><img src="'+val.url+'" width=550 /></p>');
                });
                
                dialog.close(true);}
                else
                {
                    alert('请上传文件后点击【确定】');
                }
            }
        }, {
            className: 'edui-cancelbutton',
            label: '取消',
            onclick: function() {
                dialog.close(false);
            }
        }]
    });

    //参考addCustomizeButton.js
    var btn = new UE.ui.Button({
        name: 'dialogbutton' + uiName,
        title: 'dialogbutton' + uiName,
        //需要添加的额外样式,指定icon图标,这里默认使用一个重复的icon
        cssRules: 'background-position: -580px 0;',
        onclick: function() {
            dialog.render();
            dialog.open();
        }
    });

    return btn;
} /*index 指定添加到工具栏上的那个位置,默认时追加到最后,editorId 指定这个UI是那个编辑器实例上的,默认是页面上所有的编辑器都会添加这个按钮*/ );

由于Ueditor的对话框插件是通过iframe实现的,所以还需要创建一个网页。取名为uploadPreview.html,引用css文件为fileinput.css,是一个Jquery的第三方插件的UI。实现逻辑不再赘述,直接帖代码。

uploadPreview.html

<html>
<head>
    <meta charset='utf-8'>
    <script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <link rel="stylesheet" type="text/css" href="fileinput.css">
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet">
    <style type="text/css">
    body {
        height: 440px;
        overflow: hidden;
    }
    
    form {
        margin-left: 15px;
    }
    
    .browse-btn {
        position: relative;
        display: inline-block;
        background: #D0EEFF;
        border: 1px solid #99D3F5;
        border-radius: 4px;
        padding: 4px 12px;
        overflow: hidden;
        color: #1E88C7;
        text-decoration: none;
        text-indent: 0;
        line-height: 20px;
        cursor: pointer;
    }
    
    .browse-btn:hover {
        background: #AADFFD;
        border-color: #78C3F3;
        color: #004974;
        text-decoration: none;
        cursor: pointer;
    }
    
    #upload-Img {
        width: 144px;
        height: 41px;
        cursor: pointer;
        font-size: 30px;
        outline: medium none;
        position: absolute;
        filter: alpha(opacity=0);
        -moz-opacity: 0;
        opacity: 0;
        left: 0px;
        top: 0px;
    }
    
    #uploadEach {
        float: left;
    }
    
    form {
        width: 100%;
    }
    </style>
</head>

<body>
    <div class='file-preview-thumbnails file-drop-zone'>
    </div>
    <form>
        <a href="#" class="browse-btn">+添加文件
        <input id='upload-Img' type="file" name="photo" onchange="readFiles(event)" />
        </a>
        <a href="#" id="upload-each" class="browse-btn">上传所有文件</a>
    </form>
    <div id='jsonData' style="display:none"></div>
    <script type="text/javascript">
    var resultJson = [];
    var serverUrl = window.location.href.split('=')[1];
    if (serverUrl == null) {
        console.error('serverUrl为空!');
    }

    serverUrl = serverUrl + '?action=uploadimagebase64';

    $('#upload-each').click(function(event) {
        var l = $('.file-preview-thumbnails').find('img').length;
        if (l == 0) {
            alert('请选择要添加的文件!');
        } else {
            $('.file-preview-thumbnails').find('img').each(function(index, el) {
                uploadOneImg($(this).attr('randid'));
            });
        }
    });

    function uploadOneImg(randId) {
        urlData = $('#preview-' + randId).find('img').attr('src');
        $.ajax({
            //contentType: 'application/json; charset=utf-8',
            type: 'post',
            url: serverUrl,
            data: {
                upfile: urlData
            },
            datatype: 'json',
            success: function(data) {
                var obj = eval('(' + data + ')');
                if (obj.state == 'SUCCESS') {
                    var icon = $('#preview-' + randId).find('.file-upload-indicator');
                    if (resultJson.length == 0) {
                        resultJson = jQuery.parseJSON('[' + data + ']');
                    } else {
                        resultJson.push(jQuery.parseJSON(data));
                    }
                    $('#jsonData').html(JSON.stringify(resultJson));
                    //icon.attr('title', '上传成功');
                    //icon.removeClass('glyphicon-hand-down'); 
                    //icon.removeClass('glyphicon-hand-down'); 
                    //icon.addClass('glyphicon glyphicon-ok-sign text-success');
                    icon.find('i').removeClass();
                    icon.find('i').addClass('glyphicon glyphicon-ok-sign text-success');
                    $('#preview-' + randId).find('.file-footer-buttons').find('.kv-file-upload').remove();
                    $('.file-thumb-progress').removeClass('hide');
                    $('.progress-bar').html('100%');
                    $('.progress-bar').css('width', '100%');
                } else {
                    var icon = $('#preview-' + randId).find('.file-upload-indicator');
                    icon.find('i').removeClass();
                    icon.find('i').addClass('glyphicon glyphicon-alert text-warning');
                    console.error(obj.state);
                }
                //alert('成功!');
            },
            error: (function() {
                alert('上传失败');
            })
        });
    }

    function _getRandomString(len) {
        len = len || 32;
        var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; // 默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1
        var maxPos = $chars.length;
        var pwd = '';
        var i;
        for (i = 0; i < len; i++) {
            pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
        }
        return pwd;
    }

    function createPreviewEl(randId, i, base64, title) {
        var innerHTML = '<div class="file-actions"><div class = "file-footer-buttons"><button type = "button" randid="' + randId + '" class = "kv-file-upload btn btn-xs btn-default" title="上传文件"> <i class = "glyphicon glyphicon-upload text-info"> </i> </button> <button type = "button" randid="' + randId + '" class = "kv-file-remove btn btn-xs btn-default"title = "删除文件"> <i class = "glyphicon glyphicon-trash text-danger"> </i></button></div> <div class = "file-upload-indicator" title = "没有上传"> <i class = "glyphicon glyphicon-hand-down text-warning"> </i></div><div class = "clearfix" > </div></div>';
        var el = $('<div/>');
        el.addClass('file-preview-frame');
        el.attr('id', 'preview-' + randId);
        el.attr('data-fileindex', i);
        var elImage = $('<img/>');
        elImage.attr('src', base64);
        elImage.css('height', '90px');
        elImage.addClass('file-preview-image');
        elImage.attr('title', title);
        elImage.attr('alt', title);
        elImage.attr('randid', randId);
        var elFooter = $('<div/>');
        elFooter.addClass('file-thumbnail-footer');
        elFooter.html(innerHTML);
        elFooter.append(
            $('<div/>').html(title)
            .addClass('file-footer-caption')
            .append($('<div/>').addClass('file-thumb-progress')
                .addClass('hide')
                .html('<div class="progress"><div class="progress-bar progress-bar-success progress-bar-striped active" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width:0%;">0%</div></div>')
            )
        );
        el.append(elImage);
        el.append(elFooter);
        return el;
    }

    function readFiles(evt) {
        var files = evt.target.files;
        //console.log(files.length);
        if (!files) {
            alert("文件不支持");
            return;
        }
        for (var i = 0; i < files.length; i++) {
            //alert(files[i]);
            var drawX = 0;
            var drawY = 0;
            var imgele = new Image();
            var thesrc = window.URL.createObjectURL(files[i]);
            imgele.src = thesrc;
            imgele.onload = function() {
                var randId = _getRandomString(5);
                var scale = null; //计算长宽比
                var maxHeight = 800;
                var maxWidth = 1024;
                var privewWidth = 200;
                var privewHeight = 0;
                scale = imgele.height / imgele.width;
                if (imgele.width <= maxWidth && imgele.height <= maxHeight) {
                    drawX = imgele.width;
                    drawY = imgele.height;
                    //privewHeight = 200 * scale;
                } else {
                    if (scale < 1) {
                        drawX = maxWidth;
                        drawY = Math.ceil(maxWidth * scale);
                    } else {
                        drawY = maxHeight;
                        drawX = Math.ceil(maxHeight / scale);
                    }
                }
                var canvas = document.createElement("canvas");
                canvas.setAttribute("width", drawX);
                canvas.setAttribute("height", drawY);
                canvas.innerHTML = "你的浏览器不支持";
                var cxt = canvas.getContext("2d");
                cxt.drawImage(this, 0, 0, drawX, drawY);
                var dataurl = canvas.toDataURL('image/jpg');
                $('.file-preview-thumbnails').append(createPreviewEl(randId, i, dataurl, ''));
                $('.kv-file-upload').click(function(event) {
                    uploadOneImg($(this).attr('randid'));
                });
                $('.kv-file-remove').click(function(event) {
                    var id=$(this).attr('randid');
                    $('#preview-' + id).remove();
                });
            }

        }
    }
    </script>
</body>

</html>

实现UI效果如下图

56c1ec59b37a5.jpg

标签: none

有0条评论

添加新评论