前言

  众所周知,Dotnet Core目前没有图形API,以前的System.Drawing程序集并没有包含在Dotnet Core 1.0环境中。不过在dotnet core labs项目里可以见到MS已经在移植这个项目,不过目前的版本只能在Windows上和NET541+或DNX环境中才可以使用。

  不过在dotnetConf的第两天有一个叫做SkiaSharp的开源项目被提及;它是Google开源的跨平台2D图形API,Skia的.NET封装;目前只能在Full Framework上运行,不过它以后会支持Core。

现状

  据我了解,Dotnet Core目前没有可用的验证码组件可用,原因就是没有Core的图形接口。所以我的方案是通过开源的图形库来对dotnet core进行支持。

使用CImg开源库

  CImg 库是一个免费、开源的图像处理C++库,名称原意是 Cool Image,正如其名,CImg是一个非常优秀、功能强大、代码简洁、使用方便的C++ 图像处理库。它不仅非常适合科学家、研究生做科研时使用,也适合在工业应用工程开发中使用,更适合的是,对于有志于开发简洁、高效、功能强大的图像处理库的人而言,CImg的源码是不可多得的学习和参考资料。

  CImg 官网:http://cimg.sourceforge.net/

  可移植性:它完全兼容于操作系统如Windows, Unix, Linux, MacOS X, *BSD...,也完全兼容与编译器如 VC++, g++, icc...等,具有高度的可移植性。

  轻便性:CImg 非常轻便,整个库只用一个文件:cimg.h。任何C++应用程序只需要将该头文件包含进工程中即可使用该库的全部功能。它只定义了四了类(模板)和两个名称空间。该库只依赖与标准C++和STL,只在显示类部分依赖与操作系统的GDI,再也不依赖任何其他的外部库。

C++封装:

  我把绘图逻辑都放到了一个C++项目中,再用Core项目使用DllImport进行调用。

  而且想到跨平台在Win下我们使用Win32的DLL库进行编译,在Linux下使用g++直接对源代码进行链接编译;

  下面是项目中最主要的CaptchaImage.cpp,Win32下它会被放到项目中

 #include "stdafx.h"
#include "CaptchaImage.h"
#include "CImg.h"
using namespace cimg_library; Export_API void GCaptcha(char* file_o, char *captcha_text, int count, int width ,int height , int offset ,int quality, int isjpeg, int fontSize)
{
// Create captcha image
//----------------------
// Write colored and distorted text
CImg<unsigned char> captcha(width, height, , , ), color();
const unsigned char red[] = { ,, }, green[] = { ,, }, blue[] = { ,, }; char letter[] = { };
for (unsigned int k = ; k<count; ++k) {
CImg<unsigned char> tmp;
*letter = captcha_text[k];
if (*letter) {
cimg_forX(color, i) color[i] = (unsigned char)( + (std::rand() % ));
tmp.draw_text((int)( + * cimg::rand()),
(int)( * cimg::rand()), letter, red, , , fontSize).resize(-, -, , ); const float sin_offset = (float)cimg::crand() * , sin_freq = (float)cimg::crand() / ; cimg_forYC(captcha, y, v) captcha.get_shared_row(y, , v).shift((int)( * std::cos(y*sin_freq + sin_offset))); captcha.draw_image(count + offset * k, tmp);
}
} // Add geometric and random noise
CImg<unsigned char> copy = (+captcha).fill();
for (unsigned int l = ; l<; ++l) {
if (l) copy.blur(0.5f).normalize(, );
for (unsigned int k = ; k<; ++k) {
cimg_forX(color, i) color[i] = (unsigned char)( + cimg::rand() * );
if (cimg::rand() < 0.5f) {
copy.draw_circle((int)(cimg::rand()*captcha.width()),
(int)(cimg::rand()*captcha.height()),
(int)(cimg::rand() * ),
color.data(), 0.6f, ~0U);
}
else {
copy.draw_line((int)(cimg::rand()*captcha.width()),
(int)(cimg::rand()*captcha.height()),
(int)(cimg::rand()*captcha.width()),
(int)(cimg::rand()*captcha.height()),
color.data(), 0.6f);
}
}
}
captcha |= copy;
captcha.noise(, ); captcha = (+captcha).fill() - captcha; // Write output image and captcha text
//-------------------------------------
//std::printf("%s\n",captcha_text); if (isjpeg) {
captcha.save_jpeg(file_o, quality);
}
else {
captcha.save(file_o);
} }

CaptchaImage.cpp

  头文件:

 #ifdef PROJECT_EXPORTS
#define Export_API extern "C" __declspec(dllexport)
#else
#define Export_API extern "C"
#endif Export_API void GCaptcha(char* file_o, char *captcha_text, int count, int width, int height, int offset, int quality, int isjpeg, int fontSize);

CaptchaImage.h

  这里为了跨平台编译我将stdafx.h文件进行了修改如下:

 #pragma once
#ifdef _MSC_VER //I'm in VS
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
#endif

stdafx.h

Dotnet Core平台封装:

  public class CaptchaImageCore
{ [DllImport("libcaptchaimage.so", EntryPoint = "GCaptcha")]
public static extern void libCaptcha(string file_o, string captcha_text, int count, int width, int height, int offset, int quality, int isjpeg, int fontSize); [DllImport("libcaptchaimage.dll", EntryPoint = "GCaptcha")]
public static extern void GCaptcha(string file_o, string captcha_text, int count, int width, int height, int offset, int quality, int isjpeg, int fontSize); public string Text { set; get; } public int ImageWidth { set; get; }
public int ImageHeight { set; get; } public int ImageOffset { set; get; } public int ImageQuality { set; get; } public int FontSize { set; get; } public CaptchaImageCore(int w,int h,int fontSize)
{
this.ImageWidth = w;
this.ImageHeight = h;
this.FontSize = fontSize;
this.ImageOffset = ;
this.ImageQuality = ; } public MemoryStream GetStream(string fileName)
{
this.Save(fileName);
MemoryStream ms = new MemoryStream();
using (var fileStream = new FileStream(fileName, FileMode.Open))
{
fileStream.CopyTo(ms);
}
try
{
File.Delete(fileName);
}
catch { }
return ms; } public void Save(string fileName)
{
if (string.IsNullOrEmpty(fileName))
throw new NullReferenceException("file name is null");
if (string.IsNullOrEmpty(this.Text))
this.Text = this.GenerateCheckCode(); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
GCaptcha(fileName, this.Text, this.Text.Length, this.ImageWidth, this.ImageHeight,
this.ImageOffset, this.ImageQuality, , this.FontSize);
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
libCaptcha(fileName, this.Text, this.Text.Length, this.ImageWidth, this.ImageHeight,
this.ImageOffset, this.ImageQuality, , this.FontSize);
}
} public string GenerateCheckCode()
{
int number;
char code;
string checkCode = String.Empty; System.Random random = new Random(); for (int i = ; i < ; i++)
{
number = random.Next(); if (number % == )
//生成'0'-'9'字符
code = (char)('' + (char)(number % ));
else
//生成'A'-'Z'字符
code = (char)('A' + (char)(number % )); checkCode += code.ToString();
} return checkCode;
//两个字符相加等于=asicc码加
} }

LibCaptchaImageWarp.cs

编译:

Win32编译就不用说了,直接在VS2015里编译就好,但是一定要注意的是,要编译为X64平台的目标代码,因为我们的Dotnet Core只支持x64平台;

主要说下Linux编译,目前我只在Ubuntu 14.04进行了编译测试,编译时CImg依赖也X11,所以要在编译环境中安装X11开发库,当然Ubuntu也需要64位;

sudo apt-get install libx11-dev

接下下是编译:

把那个Win32项目Copy到Linux中,然后Bash到目录下执行:

g++ CaptchaImage.cpp -fPIC -shared -o libcaptchaimage.so

然后当你发布程序时一定要将libcaptachaImageWarp.dll 和 Win32 Dll 或 libcaptchaimage.so 文件一起放到程序执行目录。

最后:

看看效果吧:

验证码源码:https://github.com/maxzhang1985/YOYOFx/tree/master/Native

Demo:https://github.com/maxzhang1985/YOYOFx/tree/master/CoreHost

QQ群:214741894

Demo和源码在:https://github.com/maxzhang1985/YOYOFx

YOYOFx是一个基于Core和Owin的框架,项目没有依赖微软的MVC框架,支持在.net 4.5和Mono上直接SelfHost或使用Tinyfox跨平台运行, 也支持在Dotnet Core 1.0 RC2 实现跨平台运行; 框架刚刚写出来还没有文档,请大家见谅。

欢迎大家Star和Fork

【干货】”首个“ .NET Core 验证码组件的更多相关文章

  1. kaptcha 验证码组件使用

    kaptcha 验证码组件使用简介   kaptcha 是一个非常实用的验证码生成工具.有了它,你可以生成各种样式的验证码,因为它是可配置的.kaptcha工作的原理是调用 com.google.co ...

  2. python安装及写一个简单的验证码组件(配合node)

    1.安装Python 到官网下载响应系统的版本(这里以windows为例):https://www.python.org/downloads/windows/ 然后就是不断地"下一步&quo ...

  3. net core体系-web应用程序-4net core2.0大白话带你入门-7asp.net core日志组件(Logger和Nlog)

    asp.net core日志组件   日志介绍 Logging的使用 1. appsettings.json中Logging的介绍 Logging的配置信息是保存在appsettings.json配置 ...

  4. 【vue】canvas验证码组件--数字/数字加字母

    基于canvas的数字/数字+字符验证码   SIdentify.vue 组件 <!-- 基于canvas的数字/数字+字符验证码 --> <!-- 调用格式 <s-ident ...

  5. .NET Core开源组件:后台任务利器之Hangfire 转载 https://www.cnblogs.com/chenug/p/6655636.html

    .NET Core开源组件:后台任务利器之Hangfire   一.简述 Hangfire作为一款高人气且容易上手的分布式后台执行服务,支持多种数据库.在.net core的环境中,由Core自带的D ...

  6. .NET Core 首例 Office 开源跨平台组件(NPOI Core)

    前言 最近项目中,需要使用到 Excel 导出,找了一圈发现没有适用于 .NET Core的,不依赖Office和操作系统限制的 Office 组件,于是萌生了把 NPOI 适配并移植到 .NET C ...

  7. .NET Core性能测试组件BenchmarkDotNet 支持.NET Framework Mono

    .NET Core 超强性能测试组件BenchmarkDotNet 支持Full .NET Framework, .NET Core (RTM), Mono. BenchmarkDotNet支持 C# ...

  8. 【腾讯Bugly干货分享】微信终端跨平台组件 mars 系列(二) - 信令传输超时设计

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:http://mp.weixin.qq.com/s/9DJxipJaaBC8yC-buHgnTQ 作者简介: ...

  9. 一个技术汪的开源梦 —— 基于 .Net Core 的组件 Nuget 包制作 & 发布

    一个技术汪的开源梦 —— 目录 微软的 ASP.Net Core 强化了 Nuget 的使用,所有的 .Net Core 组件均有 Nuget 管理,所以有必要探讨一下 .Net Core 组件制作 ...

随机推荐

  1. URL安全的Base64编码

    Base64编码可用于在HTTP环境下传递较长的标识信息.在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式.此时,采用Base64编码不仅比较简短,同时也具有不可 ...

  2. 【深入浅出jQuery】源码浅析--整体架构

    最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...

  3. Dapper逆天入门~强类型,动态类型,多映射,多返回值,增删改查+存储过程+事物案例演示

    Dapper的牛逼就不扯蛋了,答应群友做个入门Demo的,现有园友需要,那么公开分享一下: 完整Demo:http://pan.baidu.com/s/1i3TcEzj 注 意 事 项:http:// ...

  4. HTML文档声明

    前面的话   HTML文档通常以类型声明开始,该声明将帮助浏览器确定其尝试解析和显示的HTML文档类型.本文将详细介绍文档声明DOCTYPE 特点   文档声明必须是HTML文档的第一行.且顶格显示, ...

  5. 关于python的bottle框架跨域请求报错问题的处理

    在用python的bottle框架开发时,前端使用ajax跨域访问时,js代码老是进入不了success,而是进入了error,而返回的状态却是200.url直接在浏览器访问也是正常的,浏览器按F12 ...

  6. 理解nodejs模块的scope

    描述 原文档地址:https://docs.npmjs.com/misc/scope 所有npm模块都有name,有的模块的name还有scope.scope的命名规则和name差不多,同样不能有ur ...

  7. Hawk 6. 高级话题:子流程系统

    子流程的定义 当流程设计的越来越复杂,越来越长时,就难以进行管理了.因此,采用模块化的设计才会更加合理.本节我们介绍子流程的原理和使用. 所谓子流程,就是能先构造出一个流程,然后被其他流程调用.被调用 ...

  8. PayPal高级工程总监:读完这100篇论文 就能成大数据高手(附论文下载)

    100 open source Big Data architecture papers for data professionals. 读完这100篇论文 就能成大数据高手 作者 白宁超 2016年 ...

  9. python 数据类型 -- 元组

    元组其实是一种只读列表, 不能增,改, 只可以查询 对于不可变的信息将使用元组:例如数据连接配置 元组的两个方法: index, count >>> r = (1,1,2,3) &g ...

  10. interpreter(解释器模式)

    一.引子 其实没有什么好的例子引入解释器模式,因为它描述了如何构成一个简单的语言解释器,主要应用在使用面向对象语言开发编译器中:在实际应用中,我们可能很少碰到去构造一个语言的文法的情况. 虽然你几乎用 ...