C#实现旋转图片验证码
开发环境:C#,VS2019,.NET Core 3.1,ASP.NET Core
1、建立一个验证码控制器
新建两个方法Create和Check,Create用于创建验证码(返回1张图片和令牌),Check用于验证(验证图片旋转角度)它是否有效。
声明一个静态类变量存放列表,列表中存放包含令牌和验证码的对象。
/// <summary>/// 返回一张图片和令牌./// </summary>/// <returns></returns>public string Create(){try{// 记录验证码到缓存中VCodeCircleModel model = new VCodeCircleModel();model.id = Guid.NewGuid().ToString(); // 生成令牌var vcode = VCodeCircleModel.GetVCode(); // 生成验证码model.code = vcode;_list.Add(model);// 返回图片var images = VCodeCircleModel.GetImage(Convert.ToInt32(vcode));VCodeCircleController_Create_Receive result = new VCodeCircleController_Create_Receive();result.code = "0";result.data.id = model.id;result.data.img = VCodeCircleModel.BitmapToBase64Str(images);var json = JsonConvert.SerializeObject(result);return json;}catch (Exception ex){_logger.LogWarning(exception: ex, message: ex.Message);VCodeCircleController_Create_Receive result = new VCodeCircleController_Create_Receive();result.code = "999999";result.msg = "系统异常";var json = JsonConvert.SerializeObject(result);return json;}}public string Check(string id, string code){try{// 旋转图片的误差在±5var temp = Convert.ToInt32(code) - 5;var index = _list.FindIndex(m =>{if (m.id.Equals(id)){for (int i = 0; i < 10; i++){if (m.code.Equals(temp.ToString())){return true;}temp++;}}return false;});ReceiveObject result = new ReceiveObject();if (index >= 0){_list.RemoveAt(index);result.code = "0";result.msg = "验证成功";var json = JsonConvert.SerializeObject(result);return json;}else{result.code = "1";result.msg = "验证失败";var json = JsonConvert.SerializeObject(result);return json;}}catch (Exception ex){_logger.LogError(exception: ex, message: ex.Message);ReceiveObject result = new ReceiveObject();result.code = "999999";result.msg = "系统异常";var json = JsonConvert.SerializeObject(result);return json;}}
public class VCodeCircleModel{/// <summary>/// 令牌./// </summary>public string id { get; set; }/// <summary>///验证码./// </summary>public string code { get; set; }/// <summary>/// 获取随机验证码./// </summary>/// <returns></returns>public static string GetVCode(){// 这里的随机码是旋转图片的角度,至少旋转60度,最多旋转300度Random random = new Random();return random.Next(60, 300).ToString();}/// <summary>/// 随机获取一张图片./// </summary>/// <returns></returns>public static Bitmap GetImage(int angle){// 从文件加载原图Random random = new Random();var image_index = random.Next(0, 2);Image originImage;switch (image_index){case 0:originImage = Image.FromFile(string.Format(@"{0}\Images\{1}", PathHelper.Path, "circleImg1.png"));break;case 1:default:originImage = Image.FromFile(string.Format(@"{0}\Images\{1}", PathHelper.Path, "circleImg2.png"));break;}originImage = Rotate(originImage as Bitmap, angle);return (Bitmap)originImage;}/// <summary>/// 图片旋转/// </summary>/// <param name="ImageOriginal">原图.</param>/// <param name="AngleValue">旋转角度.</param>/// <returns></returns>public static Bitmap Rotate(Bitmap ImageOriginal, float AngleValue){AngleValue = AngleValue % 360;double radian = AngleValue * Math.PI / 180.0;double cos = Math.Cos(radian);double sin = Math.Sin(radian);int w = ImageOriginal.Width;int h = ImageOriginal.Height;int W = (int)(Math.Max(Math.Abs(w * cos - h * sin), Math.Abs(w * cos + h * sin)));int H = (int)(Math.Max(Math.Abs(w * sin - h * cos), Math.Abs(w * sin + h * cos)));Bitmap ImageBaseOriginal = new Bitmap(W, H, PixelFormat.Format32bppArgb);System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(ImageBaseOriginal);g.InterpolationMode = InterpolationMode.NearestNeighbor;g.SmoothingMode = SmoothingMode.HighQuality;Point Offset = new Point((W - w) / 2, (H - h) / 2);Rectangle rect = new Rectangle(Offset.X, Offset.Y, w, h);Point center = new Point(rect.X + rect.Width / 2, rect.Y + rect.Height / 2);g.Clear(Color.White);g.TranslateTransform(center.X, center.Y);g.RotateTransform(360 - AngleValue);g.TranslateTransform(-center.X, -center.Y);g.DrawImage(ImageOriginal, rect);g.ResetTransform();g.Save();g.Dispose();return ImageBaseOriginal;}/// <summary>/// 将图片对象转成Base64的字符串./// </summary>/// <param name="bitmap"></param>/// <returns></returns>public static string BitmapToBase64Str(Bitmap bitmap){using (MemoryStream memoryStream = new MemoryStream()){bitmap.Save(memoryStream, ImageFormat.Jpeg);byte[] bytes = memoryStream.ToArray();return Convert.ToBase64String(memoryStream.ToArray());}}}
2、新建一个视图文件,引入jquery,css文件,js方法中添加三个鼠标事件 - 鼠标按下,鼠标移动和鼠标松开。页面首次加载时调用控制器的Create方法获取图片和令牌,在鼠标松开时调用Check方法验证旋转的角度是否有效。
本来想实现鼠标在图片上拖动后让图片的效果,但发现难度有点大,就换成了拖动滑块后让图片旋转的形式。
<link href="~/css/circle_slide.css" rel="stylesheet" type="text/css" /><!-- 展示验证码 -->
<div class="container"><div class="main"><div id="content" class="content"><img id="backImage" src="" alt=""></div></div><div id="slider"><div id="sliderBlock"></div></div>
</div><script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/js/MyCircleSlide.js"></script>
* {margin: 0;padding: 0;
}.main {position: relative;margin-left: 20px;margin-top: 20px;width: 200px;background-color: white;
}.content {width: 100%;
}.content img {width: 100%;height: auto;}#slider {width: 85%;height: 40px;background-color: aliceblue;position: relative;
}#sliderBlock {position: absolute;left: 5px;height: 30px;width: 45px;top: 5px;background-color: white;border-radius: 5px;box-shadow: 0 0 10px 2px lightgray;
}
$(function () {var _imageBase64; // 大图var _id;// 鼠标左键是否按下var isMouseDown;// 鼠标按下x值var mouseDownStartX;// 鼠标移动距离var mouseMoveLength;init();document.onmousedown = function (event) {var obj = getElementPosition(document.getElementById('sliderBlock'))if (event.clientX > obj.left &&event.clientX < (obj.left + obj.width) &&event.clientY > obj.top &&event.clientY < (obj.top + obj.height)) {// 鼠标点击事件发生在滑动条的范围内this.isMouseDown = truethis.mouseDownStartX = event.clientXconsole.log("鼠标点击事件发生在滑动条的范围内");}}document.onmousemove = function (event) {if (this.isMouseDown) {this.mouseMoveLength = event.clientX - this.mouseDownStartX; // 计算滑块拖动的距离if (this.mouseMoveLength > 0 &&this.mouseMoveLength < 360) {// 滑块拖动的最小距离是5px,最大距离是大图的宽度 - 小图的宽度document.getElementById('sliderBlock').style.left = 5 + this.mouseMoveLength + 'px'$("#backImage").css("transform", "rotate(" + (this.mouseMoveLength) + "deg)");}}}document.onmouseup = function (event) {// 鼠标松开后停止拖动if (this.isMouseDown) {this.isMouseDown = false// console.log("小图移动了:" + this.mouseMoveLength);// check(x.replace("px", ""));check(this.mouseMoveLength);}}// dom在浏览器的位置function getElementPosition(element) {let top = element.offsetToplet left = element.offsetLeftlet width = element.offsetWidthlet height = element.offsetHeightvar currentParent = element.offsetParent;while (currentParent !== null) {top += currentParent.offsetTopleft += currentParent.offsetLeftcurrentParent = currentParent.offsetParent}return { top, left, width, height }}function check(x) {$.get("Check?code=" + x + "&id=" + _id, function (data) {var obj = JSON.parse(data);if (obj.code == "0") {alert("验证成功");}else {alert("验证失败");}});}// 设置当前图片function setCurrentImageBase64(imageBase64) {_imageBase64 = imageBase64document.getElementById('backImage').src = _imageBase64}function init() {$.get("Create", function (data) {// 获取两张图片和令牌var obj = JSON.parse(data);_id = obj.data.id;setCurrentImageBase64('data:image/webp;base64,' + obj.data.img);});}
});
效果图:


相关文章:
C#实现旋转图片验证码
开发环境:C#,VS2019,.NET Core 3.1,ASP.NET Core 1、建立一个验证码控制器 新建两个方法Create和Check,Create用于创建验证码(返回1张图片和令牌),Check用于验证(验证图…...
MySQL—缓存
目录标题 为什么要有Buffer Poolbuffer pool有多大buffer pool缓存什么 如何管理Buffer Pool如何管理空闲页如何管理脏页如何提高缓存命中率预读失效buffer pool污染 脏页什么时候会被刷入到磁盘 为什么要有Buffer Pool 虽然说MySQL的数据是存储在磁盘中,但是也不能…...
IP提取器对比器
需求: 一个html 页面 ,有两个输入框 第一个输入框输入文本中包含多个ip,输入的ip是不规则的,需要使用正则表达式提取出 输入文本的ip地址 , 然后在第二个输入框中输入内容,并提取出内容的ip ,如…...
【Spring Boot】构建RESTful服务 — RESTful简介
RESTful简介 本节将从基础的概念开始介绍什么是RESTful、RESTful的特点、RESTful中的资源、HTTP Method、HTTP Status,还将介绍RESTful和SOAP到底有哪些区别。 1.什么是RESTful RESTful是目前流行的互联网软件服务架构设计风格。REST(Representationa…...
模仿火星科技 基于cesium+水平面积测量+可编辑
当您进入Cesium的编辑水平积测量世界,下面是一个详细的操作过程,帮助您顺利使用这些功能: 1. 创建提示窗: 启动Cesium应用,地图场景将打开,欢迎您进入编辑模式。 在屏幕的一角,一个友好的提…...
26.配电网规划——考虑潮流约束的配电网规划
MATLAB代码直达:26.多时段-考虑潮流约束的配电网规划 clc;clear;close all; %% 导入数据 load(data.mat); MGpowerxlsread(MG1-3.xlsx); % 微电网的日负荷曲线 nt3 ; % 变压所个数 Sn25; % 变电所容量 MVA G…...
【云原生】K8S集群
目录 一、调度约束1.1 POT的创建过程1.1调度过程 二、指定节点调度2.1 通过标签选择节点 三、亲和性3.1requiredDuringSchedulingIgnoredDuringExecution:硬策略3.1 preferredDuringSchedulingIgnoredDuringExecution:软策略3.3Pod亲和性与反亲和性3.4使…...
python接口自动化之自动发送测试报告邮件
前言 SMTP(Simple Mail Transfer Protocol)也就是简单邮件传输协议,是一种提供可靠且有效电子邮件传输的协议。python的smtplib模块就提供了一种很方便的途径发送电子邮件,它对smtp协议进行了简单的封装。 python发邮件主…...
umi出现“Cannot find module ‘umi-build-dev/lib/routes‘“ 错误
确认安装的 Umi 版本是否正确:首先,检查项目中 package.json 文件中的 umi 的版本号是否正确,确保版本号与项目所需的版本一致。清除缓存并重新安装依赖:可以尝试使用以下命令清除 npm 缓存并重新安装依赖: npm cache …...
Redis类型检查与命令多态
Redis中用于操作键的命令基本上可以分为两种类型。 其中一种命令可以对任何类型的键执行,比如说DEL命令、EXPIRE命令 、RENAME命令、TYPE命令、OBJECT命令等。 举个例子,以下代码就展示了使用DEL命令来删除三种不同类型的键: # 字符串键 redis> SE…...
mysql支持的xa具体指的是什么?
在MySQL中,XA指的是一种事务协议(eXtended Architecture),用于支持分布式事务。XA协议允许应用程序跨多个独立的数据库资源(例如多个MySQL实例)执行分布式事务。 具体来说,XA协议提供了以下关键…...
IntelliJ Idea 编译时控制台上中文输出乱码
猜测原因是IDEA启动时未指定编码信息,故与系统编码保持一致(windows中文系统默认为GBK编码),当以UTF-8编码进行编译在控制台会以GBK编码输出,从而导致乱码 解决方案 指定Idea启动时JVM的默认编码为UTF-8 Help -> Edit Custom Options P…...
锚框【目标检测】
生成多个锚框 假设输入图像高为h,宽为w,我们以图像每个像素为中心生成不同形状的锚框,缩放比 s∈(0,1],宽高比为r>0。那么锚框的宽度和高度分别为和。当中心位置给定时, 已知宽和高的锚框是确定的。缩放比为锚框高与图像高的比值,然后得到一个正方形锚框面积。 …...
001-Spring boot 启动内置Web容器分析
目录 代码入口上下文容器 加载web容器WebServercreateWebServergetWebServerFactory():getWebServer(): 执行WebServer#start自动配置读取配置修改配置 代码入口 上下文容器 SpringApplication.run(App.class); //追踪下去发现 context createApplicationContext…...
【Cocos Creator 项目实战 】消灭星星加强版(附带完整源码工程)
本文乃Siliphen原创,转载请注明出处 目录 概述 游戏整体流程 游戏框架设计 单一职责的类 主要流程控制类 核心玩法模块 UI: 游戏世界: 本文项目的代码组织结构 作者项目实践总结 场景只有一个入口脚本 尽量少在节点上挂载脚本 构…...
2023软件测试岗必问的100个面试题【含答案】
一、测试理论 1.什么是软件测试? 答:软件测试是通过执行预定的步骤和使用指定的数据,以确定软件系统在特定条件下是否满足预期的行为。 2.测试驱动开发(TDD)是什么? 答:测试驱动开发是一种开…...
MediaExtractor MediaCodec手动解码播放音乐
MediaExtractor MediaCodec手动解码播放音乐,笔记 private class DecodeAudio implements Runnable {Overridepublic void run() {//开始播放pcmaudioTrack.play();MediaExtractor extractor null;MediaCodec codec null;Log.i(TAG, "run: init");FileOutputStrea…...
element表格+表单+表单验证结合运用
目录 一、结果展示 二、实现代码 一、结果展示 1、图片 2、描述 table中放form表单,放输入框或下拉框或多选框等; 点击添加按钮,首先验证表单,如果存在没填的就验证提醒,都填了就向下添加一行表单表…...
亚马逊云科技发布Amazon HealthScribe,使用生成式AI技术实现临床文档的自动生成
近日,亚马逊云科技在纽约峰会上推出了Amazon HealthScribe,该服务符合HIPAA(《健康保险流通与责任法案》)的相关要求,可为医疗软件供应商提供一种基于语音和文字识别的生成式AI技术,帮助其创建能够自动生成…...
Windows11安装Linux子系统,并实现服务自启动,局域网访问,磁盘挂载
Windows11安装Linux子系统,并实现服务自启动,局域网访问,磁盘挂载 一、准备工作二、安装Linux子系统(wsl2)三、为Linux子系统设置桥接网络检查wsl版本在 Hyper-V 管理器中创建虚拟交换机创建 WSL 配置文件启动wsl 四、设置Windows开机自启动L…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...
Linux基础开发工具——vim工具
文章目录 vim工具什么是vimvim的多模式和使用vim的基础模式vim的三种基础模式三种模式的初步了解 常用模式的详细讲解插入模式命令模式模式转化光标的移动文本的编辑 底行模式替换模式视图模式总结 使用vim的小技巧vim的配置(了解) vim工具 本文章仍然是继续讲解Linux系统下的…...
Easy Excel
Easy Excel 一、依赖引入二、基本使用1. 定义实体类(导入/导出共用)2. 写 Excel3. 读 Excel 三、常用注解说明(完整列表)四、进阶:自定义转换器(Converter) 其它自定义转换器没生效 Easy Excel在…...
