系列目录

目录:

  1. 前言
  2. 开发环境
  3. 知识点
  4. 初始使用
  5. 自定义工具栏
  6. 设置和读取编辑器内容
  7. 文件上传
  8. ueditor加水印

------------------------------------------------

下载地址在尾部

1.前言:之前一直用KingEditor富文本编辑器,在国产编辑器中算是顶尖的插件。但是这个编辑器集成度较差,也很久没有更新了,今天学习百度产品UEeditor使用!

2.开发环境:VS2013+MVC5

3.知识点:上传加水印功能

下载编辑器

各自选择自己语言的版本。我这里是.net版本就选择.net版本 UTF-8

同时可以选择Mini版本,Mini版本在日常也是够用的。开发版功能比较齐全,包括在线编辑WORD,地图,图表等功能。如果是普通的,比如博客类的,回复类使用的,使用mini版比较何时。

4.初次开始:

新建MVC5项目名为UEeditorForMVC,并解压下载的ueditor到Script文件夹下,utf8-net改名为UEeditor

初始部署使用:修改index.cshtml

@{
ViewBag.Title = "Home Page";
}
<script src="~/Scripts/ueditor/ueditor.config.js"></script>
<script src="~/Scripts/ueditor/ueditor.all.min.js"></script>
<script>
//加载编辑器
var ue = UE.getEditor('container', {
});
</script>
<script id="container" name="content" style=" height: 228px; " type="text/plain">
</script>

运行后出现效果,证明配置已经成功!

5.配置工具栏

有时候我们需要自定义工具栏,2个地方可以进行配置,一个是全局的配置文件ueitor.config.js,修改这个文件将导致整站所有编辑器一并修改

单独配置在加载编辑器时候触发:

<script>
//加载编辑器
var ue = UE.getEditor('container', {
toolbars: [[
'fullscreen', 'source',
'bold', 'italic', 'underline', 'forecolor', 'insertorderedlist',
'fontfamily', 'fontsize',
'justifyleft', 'justifycenter',
'link', 'unlink',
'simpleupload', 'snapscreen'
]]
});
</script>

这个加载可以发现与config.js是对应的。包括接口路径,主题等,都可以单独配置

效果如下,我只配置了最常用的工具栏

6.设置和读取编辑器内容

 ue.ready(function() {
//设置编辑器的内容
ue.setContent('hello');
//获取html内容,返回: <p>hello</p>
var html = ue.getContent();
//获取纯文本内容,返回: hello
var txt = ue.getContentTxt();
});

可以设置编辑器的内容。比如文章可以获取后调用

ue.setContent('hello');为编辑器设置内容

具体参考官方文档

7.文件上传

文件上传是本文的主要内容,我们必须了解一下接口。

controller.ashx 这是一个处理文件,继承IHttpHandler接口。所有文件的上传必须经过这个文件处理

App_Code文件夹下的UploadHandler.cs为上传处理文件。

执行顺序由controller.ashx判断处理后调用UploadHandler。

初始上传会成功,但是没有图片显示

这是因为路径文件造成

研究发现net根目录下有文件config.json。这个是一个json格式的配置文件

这里可以配置所有上传时候的参数包括,上传路径,文件命名,远程抓取路径等

我们这里只修改第11行代码即可

"imageUrlPrefix": "/Scripts/ueditor/net/", /* 图片访问路径前缀 */

修改上传路径:在62行

8.加入水印

既然我们知道修改文件为上传文件,那么修改上传处理逻辑可以加入水印

添加一个水印类

using System;
using System.Web;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.IO; public class WaterMark
{
/// <summary>
/// 图片水印
/// </summary>
/// <param name="imgPath">服务器图片相对路径</param>
/// <param name="filename">保存文件名</param>
/// <param name="watermarkFilename">水印文件相对路径</param>
/// <param name="watermarkStatus">图片水印位置 0=不使用 1=左上 2=中上 3=右上 4=左中 9=右下</param>
/// <param name="quality">附加水印图片质量,0-100</param>
/// <param name="watermarkTransparency">水印的透明度 1--10 10为不透明</param>
public static void AddImageSignPic(string imgPath, string filename, string watermarkFilename, int watermarkStatus, int quality, int watermarkTransparency)
{
if(!File.Exists(imgPath))
return;
byte[] _ImageBytes = File.ReadAllBytes(imgPath);
Image img = Image.FromStream(new System.IO.MemoryStream(_ImageBytes)); watermarkFilename = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, watermarkFilename);
if (!File.Exists(watermarkFilename))
return;
Graphics g = Graphics.FromImage(img);
//设置高质量插值法
//g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
//设置高质量,低速度呈现平滑程度
//g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
Image watermark = new Bitmap(watermarkFilename); if (watermark.Height >= img.Height || watermark.Width >= img.Width)
return; ImageAttributes imageAttributes = new ImageAttributes();
ColorMap colorMap = new ColorMap(); colorMap.OldColor = Color.FromArgb(, , , );
colorMap.NewColor = Color.FromArgb(, , , );
ColorMap[] remapTable = { colorMap }; imageAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap); float transparency = 0.5F;
if (watermarkTransparency >= && watermarkTransparency <= )
transparency = (watermarkTransparency / 10.0F); float[][] colorMatrixElements = {
new float[] {1.0f, 0.0f, 0.0f, 0.0f, 0.0f},
new float[] {0.0f, 1.0f, 0.0f, 0.0f, 0.0f},
new float[] {0.0f, 0.0f, 1.0f, 0.0f, 0.0f},
new float[] {0.0f, 0.0f, 0.0f, transparency, 0.0f},
new float[] {0.0f, 0.0f, 0.0f, 0.0f, 1.0f}
}; ColorMatrix colorMatrix = new ColorMatrix(colorMatrixElements); imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); int xpos = ;
int ypos = ; switch (watermarkStatus)
{
case :
xpos = (int)(img.Width * (float).);
ypos = (int)(img.Height * (float).);
break;
case :
xpos = (int)((img.Width * (float).) - (watermark.Width / ));
ypos = (int)(img.Height * (float).);
break;
case :
xpos = (int)((img.Width * (float).) - (watermark.Width));
ypos = (int)(img.Height * (float).);
break;
case :
xpos = (int)(img.Width * (float).);
ypos = (int)((img.Height * (float).) - (watermark.Height / ));
break;
case :
xpos = (int)((img.Width * (float).) - (watermark.Width / ));
ypos = (int)((img.Height * (float).) - (watermark.Height / ));
break;
case :
xpos = (int)((img.Width * (float).) - (watermark.Width));
ypos = (int)((img.Height * (float).) - (watermark.Height / ));
break;
case :
xpos = (int)(img.Width * (float).);
ypos = (int)((img.Height * (float).) - watermark.Height);
break;
case :
xpos = (int)((img.Width * (float).) - (watermark.Width / ));
ypos = (int)((img.Height * (float).) - watermark.Height);
break;
case :
xpos = (int)((img.Width * (float).) - (watermark.Width));
ypos = (int)((img.Height * (float).) - watermark.Height);
break;
} g.DrawImage(watermark, new Rectangle(xpos, ypos, watermark.Width, watermark.Height), , , watermark.Width, watermark.Height, GraphicsUnit.Pixel, imageAttributes); ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo ici = null;
foreach (ImageCodecInfo codec in codecs)
{
if (codec.MimeType.IndexOf("jpeg") > -)
ici = codec;
}
EncoderParameters encoderParams = new EncoderParameters();
long[] qualityParam = new long[];
if (quality < || quality > )
quality = ; qualityParam[] = quality; EncoderParameter encoderParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qualityParam);
encoderParams.Param[] = encoderParam; if (ici != null)
img.Save(filename, ici, encoderParams);
else
img.Save(filename); g.Dispose();
img.Dispose();
watermark.Dispose();
imageAttributes.Dispose();
} /// <summary>
/// 文字水印
/// </summary>
/// <param name="imgPath">服务器图片相对路径</param>
/// <param name="filename">保存文件名</param>
/// <param name="watermarkText">水印文字</param>
/// <param name="watermarkStatus">图片水印位置 0=不使用 1=左上 2=中上 3=右上 4=左中 9=右下</param>
/// <param name="quality">附加水印图片质量,0-100</param>
/// <param name="fontname">字体</param>
/// <param name="fontsize">字体大小</param>
public static void AddImageSignText(string imgPath, string filename, string watermarkText, int watermarkStatus, int quality, string fontname, int fontsize)
{
byte[] _ImageBytes = File.ReadAllBytes(imgPath);
Image img = Image.FromStream(new System.IO.MemoryStream(_ImageBytes)); Graphics g = Graphics.FromImage(img);
Font drawFont = new Font(fontname, fontsize, FontStyle.Regular, GraphicsUnit.Pixel);
SizeF crSize;
crSize = g.MeasureString(watermarkText, drawFont); float xpos = ;
float ypos = ; switch (watermarkStatus)
{
case :
xpos = (float)img.Width * (float).;
ypos = (float)img.Height * (float).;
break;
case :
xpos = ((float)img.Width * (float).) - (crSize.Width / );
ypos = (float)img.Height * (float).;
break;
case :
xpos = ((float)img.Width * (float).) - crSize.Width;
ypos = (float)img.Height * (float).;
break;
case :
xpos = (float)img.Width * (float).;
ypos = ((float)img.Height * (float).) - (crSize.Height / );
break;
case :
xpos = ((float)img.Width * (float).) - (crSize.Width / );
ypos = ((float)img.Height * (float).) - (crSize.Height / );
break;
case :
xpos = ((float)img.Width * (float).) - crSize.Width;
ypos = ((float)img.Height * (float).) - (crSize.Height / );
break;
case :
xpos = (float)img.Width * (float).;
ypos = ((float)img.Height * (float).) - crSize.Height;
break;
case :
xpos = ((float)img.Width * (float).) - (crSize.Width / );
ypos = ((float)img.Height * (float).) - crSize.Height;
break;
case :
xpos = ((float)img.Width * (float).) - crSize.Width;
ypos = ((float)img.Height * (float).) - crSize.Height;
break;
} g.DrawString(watermarkText, drawFont, new SolidBrush(Color.White), xpos + , ypos + );
g.DrawString(watermarkText, drawFont, new SolidBrush(Color.Black), xpos, ypos); ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo ici = null;
foreach (ImageCodecInfo codec in codecs)
{
if (codec.MimeType.IndexOf("jpeg") > -)
ici = codec;
}
EncoderParameters encoderParams = new EncoderParameters();
long[] qualityParam = new long[];
if (quality < || quality > )
quality = ; qualityParam[] = quality; EncoderParameter encoderParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qualityParam);
encoderParams.Param[] = encoderParam; if (ici != null)
img.Save(filename, ici, encoderParams);
else
img.Save(filename); g.Dispose();
img.Dispose();
} /// <summary>
/// 返回文件扩展名,不含“.”
/// </summary>
/// <param name="_filepath">文件全名称</param>
/// <returns>string</returns>
public static string GetFileExt(string _filepath)
{
if (string.IsNullOrEmpty(_filepath))
{
return "";
}
if (_filepath.LastIndexOf(".") > )
{
return _filepath.Substring(_filepath.LastIndexOf(".") + ); //文件扩展名,不含“.”
}
return "";
} public static string GetRamCode()
{
return DateTime.Now.ToString("yyyyMMddHHmmssffff");
}
}

WaterMark.cs

/// <summary>

/// 文字水印
/// </summary>
/// <param name="imgPath">服务器图片相对路径</param>
/// <param name="filename">保存文件名</param>
/// <param name="watermarkText">水印文字</param>
/// <param name="watermarkStatus">图片水印位置 0=不使用 1=左上 2=中上 3=右上 4=左中 9=右下</param>
/// <param name="quality">附加水印图片质量,0-100</param>
/// <param name="fontname">字体</param>
/// <param name="fontsize">字体大小</param>

AddImageSignPic方法参数解析

这样我们修改自带的UploadHandler.cs第68行try方法为

 try
{
if (!Directory.Exists(Path.GetDirectoryName(localPath)))
{
Directory.CreateDirectory(Path.GetDirectoryName(localPath));
}
file.SaveAs(localPath);
WaterMark.AddImageSignText(localPath, localPath,
"ymnets", 9,
80, "Tahoma", 12); //WaterMark.AddImageSignPic(serverFileName, serverFileName,
// "传入水印图片路径", 9,
// 80, 5);
Result.Url = savePath;
Result.State = UploadState.Success;
}

保存后调用写水印函数,完整的

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web; /// <summary>
/// UploadHandler 的摘要说明
/// </summary>
public class UploadHandler : Handler
{ public UploadConfig UploadConfig { get; private set; }
public UploadResult Result { get; private set; } public UploadHandler(HttpContext context, UploadConfig config)
: base(context)
{
this.UploadConfig = config;
this.Result = new UploadResult() { State = UploadState.Unknown };
} public override void Process()
{
byte[] uploadFileBytes = null;
string uploadFileName = null; if (UploadConfig.Base64)
{
uploadFileName = UploadConfig.Base64Filename;
uploadFileBytes = Convert.FromBase64String(Request[UploadConfig.UploadFieldName]);
}
else
{
var file = Request.Files[UploadConfig.UploadFieldName];
uploadFileName = file.FileName; if (!CheckFileType(uploadFileName))
{
Result.State = UploadState.TypeNotAllow;
WriteResult();
return;
}
if (!CheckFileSize(file.ContentLength))
{
Result.State = UploadState.SizeLimitExceed;
WriteResult();
return;
} uploadFileBytes = new byte[file.ContentLength];
try
{
file.InputStream.Read(uploadFileBytes, 0, file.ContentLength);
}
catch (Exception)
{
Result.State = UploadState.NetworkError;
WriteResult();
} Result.OriginFileName = uploadFileName; var savePath = PathFormatter.Format(uploadFileName, UploadConfig.PathFormat);
var localPath = Server.MapPath(savePath);
try
{
if (!Directory.Exists(Path.GetDirectoryName(localPath)))
{
Directory.CreateDirectory(Path.GetDirectoryName(localPath));
}
file.SaveAs(localPath);
WaterMark.AddImageSignText(localPath, localPath,
"ymnets", 9,
80, "Tahoma", 12); //WaterMark.AddImageSignPic(serverFileName, serverFileName,
// "传入水印图片路径", 9,
// 80, 5);
Result.Url = savePath;
Result.State = UploadState.Success;
}
catch (Exception e)
{
Result.State = UploadState.FileAccessError;
Result.ErrorMessage = e.Message;
}
finally
{
WriteResult();
}
}
} private void WriteResult()
{
this.WriteJson(new
{
state = GetStateMessage(Result.State),
url = Result.Url,
title = Result.OriginFileName,
original = Result.OriginFileName,
error = Result.ErrorMessage
});
} private string GetStateMessage(UploadState state)
{
switch (state)
{
case UploadState.Success:
return "SUCCESS";
case UploadState.FileAccessError:
return "文件访问出错,请检查写入权限";
case UploadState.SizeLimitExceed:
return "文件大小超出服务器限制";
case UploadState.TypeNotAllow:
return "不允许的文件格式";
case UploadState.NetworkError:
return "网络错误";
}
return "未知错误";
} private bool CheckFileType(string filename)
{
var fileExtension = Path.GetExtension(filename).ToLower();
return UploadConfig.AllowExtensions.Select(x => x.ToLower()).Contains(fileExtension);
} private bool CheckFileSize(int size)
{
return size < UploadConfig.SizeLimit;
}
} public class UploadConfig
{
/// <summary>
/// 文件命名规则
/// </summary>
public string PathFormat { get; set; } /// <summary>
/// 上传表单域名称
/// </summary>
public string UploadFieldName { get; set; } /// <summary>
/// 上传大小限制
/// </summary>
public int SizeLimit { get; set; } /// <summary>
/// 上传允许的文件格式
/// </summary>
public string[] AllowExtensions { get; set; } /// <summary>
/// 文件是否以 Base64 的形式上传
/// </summary>
public bool Base64 { get; set; } /// <summary>
/// Base64 字符串所表示的文件名
/// </summary>
public string Base64Filename { get; set; }
} public class UploadResult
{
public UploadState State { get; set; }
public string Url { get; set; }
public string OriginFileName { get; set; } public string ErrorMessage { get; set; }
} public enum UploadState
{
Success = 0,
SizeLimitExceed = -1,
TypeNotAllow = -2,
FileAccessError = -3,
NetworkError = -4,
Unknown = 1,
}

UploadHandler

这次我们再次上传预览效果

成功生成一个文字水印。这个水印类也包含了图片LOGO形式的

 WaterMark.AddImageSignPic(serverFileName, serverFileName,
"传入水印图片路径", 9,
80, 5);

注掉文字的替换这句:

我下载了博客园的LOGO,那么结果显然

模糊度和图片透明度都有关系.

文章内容到此结束,如果有关于ueditor的疑问欢迎留言!更多高级功能请访问官方网站

实例下载地址

ASP.NET MVC5+EF6+EasyUI 后台管理系统(57)-插件---ueditor使用的更多相关文章

  1. ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-前言与目录(持续更新中...)

    开发工具:VS2015(2012以上)+SQL2008R2以上数据库  您可以有偿获取一份最新源码联系QQ:729994997 价格 666RMB  升级后界面效果如下: 任务调度系统界面 http: ...

  2. ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-前言与目录(转)

    开发工具:VS2015(2012以上)+SQL2008R2以上数据库 您可以有偿获取一份最新源码联系QQ:729994997 价格 666RMB 升级后界面效果如下: 日程管理   http://ww ...

  3. ASP.NET MVC5+EF6+EasyUI 后台管理系统(63)-Excel导入和导出-自定义表模导入

    系列目录 前言 上一节使用了LinqToExcel和CloseXML对Excel表进行导入和导出的简单操作,大家可以跳转到上一节查看: ASP.NET MVC5+EF6+EasyUI 后台管理系统(6 ...

  4. ASP.NET MVC5+EF6+EasyUI 后台管理系统-WebApi的用法与调试

    1:ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-WebApi与Unity注入 使用Unity是为了使用我们后台的BLL和DAL层 2:ASP.NET MVC5+EF6+Easy ...

  5. ASP.NET MVC5+EF6+EasyUI 后台管理系统(51)-系统升级

    系统很久没有更新内容了,期待已久的更新在今天发布了,最近花了2个月的时间每天一点点,从原有系统 MVC4+EF5+UNITY2.X+Quartz 2.0+easyui 1.3.4无缝接入 MVC5+E ...

  6. ASP.NET MVC5+EF6+EasyUI 后台管理系统(58)-DAL层重构

    系列目录 前言:这是对本文系统一次重要的革新,很久就想要重构数据访问层了,数据访问层重复代码太多.主要集中增删该查每个模块都有,所以本次是为封装相同接口方法 如果你想了解怎么重构普通的接口DAL层请查 ...

  7. ASP.NET MVC5+EF6+EasyUI 后台管理系统(34)-文章发布系统①-简要分析

    系列目录 最新比较闲,为了学习下Android的开发构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(1)-前言与,虽然有点没有目的的学习,但还是了解了Andro ...

  8. ASP.NET MVC5+EF6+EasyUI 后台管理系统(54)-工作流设计-所有流程监控

    系列目录 先补充一个平面化登陆页面代码,自己更换喜欢的颜色背景 @using Apps.Common; @{ Layout = null; } <!DOCTYPE html> <ht ...

  9. ASP.NET MVC5+EF6+EasyUI 后台管理系统(56)-插件---单文件上传与easyui使用fancybox

    系列目录 https://yunpan.cn/cZVeSJ33XSHKZ  访问密码 0fc2 今天整合lightbox插件Fancybox1.3.4,发现1.3.4版本太老了.而目前easyui 1 ...

  10. ASP.NET MVC5+EF6+EasyUI 后台管理系统(38)-Easyui-accordion+tree漂亮的菜单导航

    系列目录 本节主要知识点是easyui 的手风琴加树结构做菜单导航 有园友抱怨原来菜单非常难看,但是基于原有树形无限级别的设计,没有办法只能已树形展示 先来看原来的效果 改变后的效果,当然我已经做好了 ...

随机推荐

  1. Hadoop 中利用 mapreduce 读写 mysql 数据

    Hadoop 中利用 mapreduce 读写 mysql 数据   有时候我们在项目中会遇到输入结果集很大,但是输出结果很小,比如一些 pv.uv 数据,然后为了实时查询的需求,或者一些 OLAP ...

  2. MIP改造常见问题二十问

    在MIP推出后,我们收到了很多站长的疑问和顾虑.我们将所有疑问和顾虑归纳为以下二十个问题,希望对大家理解 MIP 有帮助. 1.MIP 化后对其他搜索引擎抓取收录以及 SEO 的影响如何? 答:在原页 ...

  3. ASP.NET Core 1.1.0 Release Notes

    ASP.NET Core 1.1.0 Release Notes We are pleased to announce the release of ASP.NET Core 1.1.0! Antif ...

  4. 微软.NET Core RC2正式发布,横跨所有平台

    .NET官方博客宣布了<Announcing .NET Core RC2 and .NET Core SDK Preview 1>,正式如期发布了.NET Core RC2, 现在可以放心 ...

  5. ZIP压缩算法详细分析及解压实例解释

    最近自己实现了一个ZIP压缩数据的解压程序,觉得有必要把ZIP压缩格式进行一下详细总结,数据压缩是一门通信原理和计算机科学都会涉及到的学科,在通信原理中,一般称为信源编码,在计算机科学里,一般称为数据 ...

  6. 多线程条件通行工具——CountDownLatch

    CountDownLatch的作用是,线程进入等待后,需要计数器达到0才能通行. CountDownLatch(int)构造方法,指定初始计数. await()等待计数减至0. await(long, ...

  7. HTML 5 应用程序缓存manifest

    什么是应用程序缓存(Application Cache)? HTML5 引入了应用程序缓存,这意味着 web 应用可进行缓存,并可在没有因特网连接时进行访问. 应用程序缓存为应用带来三个优势: 离线浏 ...

  8. iOS10之Expected App Behaviors

    昨天上架到appStore的时候碰到个问题,构建好后上传到itunesconnect的的包都用不了, 显示错误为:此构建版本无效. 或者英文显示为:ITC.apps.preReleaseBuild.e ...

  9. 算是休息了这么长时间吧!准备学习下python文本处理了,哪位大大有好书推荐的说下!

    算是休息了这么长时间吧!准备学习下python文本处理了,哪位大大有好书推荐的说下!

  10. [转]nopCommerce Widgets and How to Create One

    本文转自:https://dzone.com/articles/what-are-nopcommerce-widgets-and-how-to-create-one A widget is a sta ...