ASP.NET MVC5+EF6+EasyUI 后台管理系统(57)-插件---ueditor使用
系列目录
目录:
- 前言
- 开发环境
- 知识点
- 初始使用
- 自定义工具栏
- 设置和读取编辑器内容
- 文件上传
- 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使用的更多相关文章
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-前言与目录(持续更新中...)
开发工具:VS2015(2012以上)+SQL2008R2以上数据库 您可以有偿获取一份最新源码联系QQ:729994997 价格 666RMB 升级后界面效果如下: 任务调度系统界面 http: ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-前言与目录(转)
开发工具:VS2015(2012以上)+SQL2008R2以上数据库 您可以有偿获取一份最新源码联系QQ:729994997 价格 666RMB 升级后界面效果如下: 日程管理 http://ww ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(63)-Excel导入和导出-自定义表模导入
系列目录 前言 上一节使用了LinqToExcel和CloseXML对Excel表进行导入和导出的简单操作,大家可以跳转到上一节查看: ASP.NET MVC5+EF6+EasyUI 后台管理系统(6 ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统-WebApi的用法与调试
1:ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-WebApi与Unity注入 使用Unity是为了使用我们后台的BLL和DAL层 2:ASP.NET MVC5+EF6+Easy ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(51)-系统升级
系统很久没有更新内容了,期待已久的更新在今天发布了,最近花了2个月的时间每天一点点,从原有系统 MVC4+EF5+UNITY2.X+Quartz 2.0+easyui 1.3.4无缝接入 MVC5+E ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(58)-DAL层重构
系列目录 前言:这是对本文系统一次重要的革新,很久就想要重构数据访问层了,数据访问层重复代码太多.主要集中增删该查每个模块都有,所以本次是为封装相同接口方法 如果你想了解怎么重构普通的接口DAL层请查 ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(34)-文章发布系统①-简要分析
系列目录 最新比较闲,为了学习下Android的开发构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(1)-前言与,虽然有点没有目的的学习,但还是了解了Andro ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(54)-工作流设计-所有流程监控
系列目录 先补充一个平面化登陆页面代码,自己更换喜欢的颜色背景 @using Apps.Common; @{ Layout = null; } <!DOCTYPE html> <ht ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(56)-插件---单文件上传与easyui使用fancybox
系列目录 https://yunpan.cn/cZVeSJ33XSHKZ 访问密码 0fc2 今天整合lightbox插件Fancybox1.3.4,发现1.3.4版本太老了.而目前easyui 1 ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(38)-Easyui-accordion+tree漂亮的菜单导航
系列目录 本节主要知识点是easyui 的手风琴加树结构做菜单导航 有园友抱怨原来菜单非常难看,但是基于原有树形无限级别的设计,没有办法只能已树形展示 先来看原来的效果 改变后的效果,当然我已经做好了 ...
随机推荐
- webp图片实践之路
最近,我们在项目中实践了webp图片,并且抽离出了工具模块,整合到了项目的基础模板中.传闻IOS10也将要支持webp,那么使用webp带来的性能提升将更加明显.估计在不久的将来,webp会成为标配. ...
- Swift3.0服务端开发(一) 完整示例概述及Perfect环境搭建与配置(服务端+iOS端)
本篇博客算是一个开头,接下来会持续更新使用Swift3.0开发服务端相关的博客.当然,我们使用目前使用Swift开发服务端较为成熟的框架Perfect来实现.Perfect框架是加拿大一个创业团队开发 ...
- VisualVM通过jstatd方式远程监控远程主机
配置好权限文件 [root@test bin]# cd $JAVA_HOME/bin [root@test bin]# vim jstatd.all.policy grant codebase &qu ...
- Android笔记——Button点击事件几种写法
Button点击事件:大概可以分为以下几种: 匿名内部类 定义内部类,实现OnClickListener接口 定义的构造方法 用Activity实现OnClickListener接口 指定Button ...
- CSS3 3D立方体效果-transform也不过如此
CSS3系列已经学习了一段时间了,第一篇文章写了一些css3的奇技淫巧,原文戳这里,还获得了较多网友的支持,在此谢过各位,你们的支持是我写文章最大的动力^_^. 那么这一篇文章呢,主要是通过一个3D立 ...
- C#基础篇 - 理解委托和事件
1.委托 委托类似于C++中的函数指针(一个指向内存位置的指针).委托是C#中类型安全的,可以订阅一个或多个具有相同签名方法的函数指针.简单理解,委托是一种可以把函数当做参数传递的类型.很多情况下,某 ...
- 这些.NET开源项目你知道吗?.NET平台开源文档与报表处理组件集合(三)
在前2篇文章这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧 和这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧!(第二辑)中,大伙热情高涨.再次拿出自己的私货,在.NET平台 ...
- jquery屏幕滚动计算事件总结
获取浏览器显示区域(可视区域)的高度 : $(window).height(); 获取浏览器显示区域(可视区域)的宽度 : $(window).width(); 获取页面的文档高度: $(docume ...
- [原] 利用 OVS 建立 VxLAN 虚拟网络实验
OVS 配置 VxLAN HOST A ------------------------------------------ | zh-veth0(10.1.1.1) VM A | | ---|--- ...
- 通过微信小程序看前端
前言 2016年9月22日凌晨,微信官方通过“微信公开课”公众号发布了关于微信小程序(微信应用号)的内测通知.整个朋友圈瞬间便像炸开了锅似的,各种揣测.介绍性文章在一夜里诞生.而真正收到内测邀请的公众 ...