获取点击点所在区域所能容纳最大连续空白矩形面积及顶点坐标需求分析及相关解决方案

近日拿到一个需求,通过分析思考以及查询资料得以解决,趁着不忙记录一下:

需求:

页面上放一个图片控件,载入图片之后,点击图片任何一个白色空间,找出点击点所在区域所能容纳的最大连续空白矩形面积及顶点坐标。

分析:

1、首先采用<img>标签控件显示图片并设置图片路径载入图片;
2、<img>标签给定点击事件onImageClick(event),获取点击点坐标;
3、向后台传递点击点坐标(x,y),进行相关计算;
4、后台接收点击点坐标(x,y),并获取图片宽高;
5、后台计算矩形面积及顶点坐标方法:
(1)通过for循环,以点击点坐标(x,y)为起点,向四周延展,如果相邻点亦为白色,即 bitmap.GetPixel(x, y).ToArgb()==Color.White.ToArgb()则为白色,可继续延展,否则停止该方向的延展。
(2)上下左右四个方向均做延展操作后,得到 左上角:(minX,minY),右下角:(maxX,maxY)两个顶点坐标;
(3)矩形的长:width = maxX-minX宽:height=maxY-minY面积:area=width*height
6、整合数据,向前台返回对应数据值;
7、前台处理返回值并对其进行相关显示处理。

话不多说,上代码:

前台代码片段:

HTML代码片段
<div><!--用于显示返回的顶点坐标及区域面积等信息--><p id="desc"></p>
</div>
<div><!--用于显示即将操作的图片文件--><img id="image" src="~/Content/images/pic.jpg" alt="Image" onclick="onImageClick(event)" />
</div>
JavaScript代码片段:
function onImageClick(event) {var img = document.getElementById("image");var x = event.offsetX;var y = event.offsetY;var desc = document.getElementById("desc");//通过 XMLHttpRequest 对象发送 HTTP 请求var xhr = new XMLHttpRequest();xhr.open("POST", "/Home/GetRegion", true);xhr.setRequestHeader("Content-Type", "application/json");xhr.onreadystatechange = function () {if (xhr.readyState == 4 && xhr.status == 200) {var result = JSON.parse(xhr.responseText);var point = "(" + result.Vertices[0].X + "," + result.Vertices[0].Y + ")"var point1 = "(" + result.Vertices[1].X + "," + result.Vertices[1].Y + ")"var point2 = "(" + result.Vertices[2].X + "," + result.Vertices[2].Y + ")"var thtml = "最大空白区域像素数量:" + result.Count + ",\r\n"+ "最大空白区域面积:" + result.Area + ", \n\r"+ "点击点坐标:" + point + ", \n\r"+ "顶点:\r\n左上:" + point1 + ",右下:" + point2 ;desc.innerHTML = thtml;alert(thtml);}};// 传递参数xhr.send(JSON.stringify({ x: x, y: y }));
}
代码解释:
var xhr = new XMLHttpRequest();
xhr.open("POST", "/Home/GetRegion", true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () { };
xhr.send(JSON.stringify({ x: x, y: y }));

这段代码是一个通过 XMLHttpRequest 对象发送 HTTP 请求的示例,主要是在浏览器中通过 JavaScript 与服务器进行交互。以下是代码的详细解析:

a、创建一个 XMLHttpRequest 对象:
var xhr = new XMLHttpRequest();

这行代码创建了一个新的 XMLHttpRequest 对象 xhr。这个对象用于在客户端与服务器之间进行数据交换。

b、配置请求类型和目标 URL:
xhr.open("POST", "/Home/GetRegion", true);

“POST”:表示请求方法是 POST,这意味着数据会被发送到服务器。
“/Home/GetRegion”:这是请求的 URL,表示将向服务器的 /Home/GetRegion 路径发送请求。
true:这是一个布尔值,表示请求是异步的。即在发送请求后不会阻塞代码的执行,直到请求完成才会触发回调。

c、设置请求头:
xhr.setRequestHeader("Content-Type", "application/json");

这行代码设置请求的头部,指定请求体的数据格式是 JSON。这样服务器就知道接收到的数据是 JSON 格式,需要进行相应的解析。

d、定义请求的回调函数:
xhr.onreadystatechange = function () {};

onreadystatechangeXMLHttpRequest 对象的一个事件,当请求的状态发生变化时,会触发该事件。function () {} 是该事件触发时调用的空回调函数。通常在这个回调函数中可以处理请求成功后的操作,如响应的处理。

e、发送请求:
xhr.send(JSON.stringify({ x: x, y: y }));

这行代码使用 send 方法将数据发送给服务器。JSON.stringify({ x: x, y: y }) xy的值封装成一个 JSON 对象,并将其转换为字符串后发送到服务器。

后台代码片段

(1)后台代码(接收前台传递点击点坐标):
/// <summary>
/// 获取点击点向四周延展所得连续最大矩形区域面积及顶点坐标
/// </summary>
/// <param name="clickPoint">点击点横纵坐标</param>
/// <returns></returns>
[HttpPost]
public JsonResult GetRegion([System.Web.Http.FromBody] ClickPoint clickPoint)
{//加载图片string path = clickPoint.ImagePath == null ? "/Content/Images/pic.jpg" : clickPoint.ImagePath;string imagePath = Server.MapPath("~" + path);Bitmap image = new Bitmap(imagePath);//获取区域相关信息RegionResult result = FindLargestBlankRegion(image, clickPoint.X, clickPoint.Y);return Json(result);
}
(2)获取顶点坐标及矩形面积计算方法:
/// <summary>
/// 计算顶点坐标及矩形面积
/// </summary>
/// <param name="image">图片信息</param>
/// <param name="startX">起始点X坐标</param>
/// <param name="startY">起始点Y坐标</param>
/// <returns></returns>
private RegionResult FindLargestBlankRegion(Bitmap image, int startX, int startY)
{// 获取 ARGB 值为 #FFFFFFFF 的系统定义的颜色Color emptyColor = Color.White;// 获取图片的宽高int width = image.Width;int height = image.Height;//包含像素数量listList<Point> regionPoints = new List<Point>();// 计算最大区域的四个顶点int minX = startX, maxX = startX, minY = startY, maxY = startY;#region 分别向四个方向扩展//向上扩展for (int i = startY; i >= 0; i--){if (IsEmptyColor(image.GetPixel(startX, i), emptyColor)){minY = i;regionPoints.Add(new Point(startX, i));}else{break;}}//向下扩展for (int i = startY; i < height; i++){if (IsEmptyColor(image.GetPixel(startX, i), emptyColor)){maxY = i;regionPoints.Add(new Point(startX, i));}else{break;}}//向左扩展for (int i = startX; i >= 0; i--){if (IsEmptyColor(image.GetPixel(i, startY), emptyColor)){minX = i;regionPoints.Add(new Point(i, startY));}else{break;}}//向右扩展for (int i = startX; i < width; i++){if (IsEmptyColor(image.GetPixel(i, startY), emptyColor)){maxX = i;regionPoints.Add(new Point(i, startY));}else{break;}}#endregion//计算扩展的矩形区域int areaWidth = maxX - minX;int areaHeight = maxY - minY;int pixelArea = areaWidth * areaHeight;var vertices = new List<Point>{new Point(startX,startY),new Point(minX,minY),new Point(maxX,maxY),};return new RegionResult{Count = regionPoints.Count,//区域所包含像素数Width = areaWidth,//区域宽Height = areaHeight,//区域高Area = pixelArea,//区域面积Vertices = vertices//顶点坐标};
}
(3)其他后台代码:
#region 公共方法/// <summary>
/// 定义颜色比较函数,比较ARGB值是否相等
/// </summary>
/// <param name="color"></param>
/// <param name="emptyColor"></param>
/// <returns></returns>
bool IsEmptyColor(Color color, Color emptyColor)
{return color.ToArgb() == emptyColor.ToArgb();
}#endregion#region Model
public class RegionResult
{public int Width { get; set; }public int Height { get; set; }public int Count { get; set; }public int Area { get; set; }public List<Point> Vertices { get; set; }
}public class ClickPoint
{public int X { get; set; }public int Y { get; set; }public string ImagePath { get; set; }
}
#endregion

考虑到有通过点击用户所上传图片进行相关操作的情况,故而添加了如下上传图片相关代码操作:

上传文件

前台上传图片代码片段
<input type="file" id="fileInput" />
前台上传图片并向后端传递文件方法
//处理图片上传
document.getElementById("fileInput").addEventListener("change", function (e) {const formData = new FormData();var file = e.target.files[0];if (file) {formData.append('file', file);//上传图片到服务器$.ajax({url: "/Home/UploadImage",type: "POST",data: formData,contentType: false,processData: false,success: function (res) {const imgElement = document.getElementById("image");imgElement.src = res.imagePath;//获取并显示上传的文件路径},error: function (xhr, status, error) {console.log("error uploading image: ", error);}});}
});
后台接收图片并上传至服务器
[HttpPost]
public ActionResult UploadImage(HttpPostedFileBase file)
{if (file != null && file.ContentLength > 0){string date = DateTime.Now.Ticks.ToString();// Define the directory to save the uploaded filevar path = Path.Combine(Server.MapPath("~/Content/Upload"), date + "_" + file.FileName);// Save the file to the serverfile.SaveAs(path);// Return the relative path of the saved filereturn Json(new { success = true, imagePath = "/Content/Upload/" + date + "_" + file.FileName });}return Json(new { success = false, message = "No file uploaded." });
}

以上就是大概的解决思路及相关代码,详细代码请移步 Gitee 查看!!!


以上内容均为本人拙见,欢迎大家留言纠正及补充,愿与大家共勉~~~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/web/81263.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue-cli 构建打包优化(JeecgBoot-Vue2 配置优化篇)

项目&#xff1a;jeecgboot-Vue2 在项目二次开发后&#xff0c;在本人电脑打包时间为3分35秒左右 webpack5默认优化&#xff1a; Tree Shaking&#xff08;摇树优化&#xff09;&#xff1a;删除未使用的代码base64 内联&#xff1a; 小于 8KB 的资源&#xff08;图片等&…

科学养生:解锁现代健康生活新方式

在现代社会&#xff0c;熬夜加班、外卖快餐、久坐不动成了很多人的生活常态&#xff0c;由此引发的亚健康问题日益凸显。其实&#xff0c;遵循科学的养生方式&#xff0c;无需复杂操作&#xff0c;从日常细节调整&#xff0c;就能显著提升健康水平。​ 饮食上&#xff0c;把控…

PostGIS使用小结

文章目录 PostGIS使用小结简介安装配合postgres使用的操作1.python安装gdal PostGIS使用小结 简介 PostGIS 是 PostgreSQL 数据库的地理空间数据扩展&#xff0c;通过为 PostgreSQL数据库增加地理空间数据类型、索引、函数和操作符&#xff0c;使其成为功能强大的空间数据库&…

NNG和DDS

NNG (Nanomsg Next Generation) 和 DDS (Data Distribution Service) 是两种不同的通信协议&#xff0c;各自在不同场景下具有其优势。下面我将对这两种技术进行详细解释&#xff0c;并通过具体的例子来说明它们如何应用在实际场景中。 1. NNG (Nanomsg Next Generation) NNG简…

自制操作系统day7(获取按键编码、FIFO缓冲区、鼠标、键盘控制器(Keyboard Controller, KBC)、PS/2协议)

day7 获取按键编码&#xff08;hiarib04a&#xff09; void inthandler21(int *esp) {struct BOOTINFO *binfo (struct BOOTINFO *) ADR_BOOTINFO; // 获取系统启动信息结构体指针unsigned char data, s[4]; // data: 键盘数据缓存&#x…

Javase 基础加强 —— 09 IO流第二弹

本系列为笔者学习Javase的课堂笔记&#xff0c;视频资源为B站黑马程序员出品的《黑马程序员JavaAI智能辅助编程全套视频教程&#xff0c;java零基础入门到大牛一套通关》&#xff0c;章节分布参考视频教程&#xff0c;为同样学习Javase系列课程的同学们提供参考。 01 缓冲字节…

服务器操作系统调优内核参数(方便查询)

fs.aio-max-nr1048576 #此参数限制并发未完成的异步请求数目&#xff0c;应该设置避免I/O子系统故障 fs.file-max1048575 #该参数决定了系统中所允许的文件句柄最大数目&#xff0c;文件句柄设置代表linux系统中可以打开的文件的数量 fs.inotify.max_user_watches8192000 #表…

[Windows] 格式工厂 FormatFactory v5.20.便携版 ——多功能媒体文件转换工具

想要轻松搞定各类媒体文件格式转换&#xff1f;这款 Windows 平台的格式工厂 FormatFactory v5.20 便携版 正是你的不二之选&#xff01;无需安装&#xff0c;即开即用&#xff0c;为你带来高效便捷的文件处理体验。 全能格式转换&#xff0c;满足多元需求 软件功能覆盖视频、…

[AI]主流大模型、ChatGPTDeepseek、国内免费大模型API服务推荐(支持LangChain.js集成)

主流大模型特色对比表 模型核心优势适用场景局限性DeepSeek- 数学/代码能力卓越&#xff08;GSM8K准确率82.3%&#xff09;1- 开源生态完善&#xff08;支持医疗/金融领域&#xff09;7- 成本极低&#xff08;API价格仅为ChatGPT的2%-3%&#xff09;5科研辅助、代码开发、数据…

国际荐酒师(香港)协会亮相新西兰葡萄酒巡展深度参与赵凤仪大师班

国际荐酒师&#xff08;香港&#xff09;协会率团亮相2025新西兰葡萄酒巡展 深度参与赵凤仪MW“百年百碧祺”大师班 广州/上海/青岛&#xff0c;2025年5月12-16日——国际荐酒师&#xff08;香港&#xff09;协会&#xff08;IRWA&#xff09;近日率专业代表团出席“纯净独特&…

Node.js Express 项目现代化打包部署全指南

Node.js Express 项目现代化打包部署全指南 一、项目准备阶段 1.1 依赖管理优化 # 生产依赖安装&#xff08;示例&#xff09; npm install express mongoose dotenv compression helmet# 开发依赖安装 npm install nodemon eslint types/node --save-dev1.2 环境变量配置 /…

java基础知识回顾3(可用于Java基础速通)考前,面试前均可用!

目录 一、基本算数运算符 二、自增自减运算符 三、赋值运算符 四、关系运算符 五、逻辑运算符 六、三元运算符 七、 运算符的优先级 八、小案例&#xff1a;在程序中接收用户通过键盘输入的数据 声明&#xff1a;本文章根据黑马程序员b站教学视频做的笔记&#xff0c;可…

随机密码生成器:原理、实现与应用(多语言实现)

在当今数字化的时代&#xff0c;信息安全至关重要。而密码作为保护个人和敏感信息的第一道防线&#xff0c;其安全性直接关系到我们的隐私和数据安全。然而&#xff0c;许多人在设置密码时往往使用简单、易猜的组合&#xff0c;如生日、电话号码或常见的单词&#xff0c;这使得…

TypeScript 泛型讲解

如果说 TypeScript 是一门对类型进行编程的语言&#xff0c;那么泛型就是这门语言里的&#xff08;函数&#xff09;参数。本章&#xff0c;我将会从多角度讲解 TypeScript 中无处不在的泛型&#xff0c;以及它在类型别名、对象类型、函数与 Class 中的使用方式。 一、泛型的核…

SQL 每日一题(6)

继续做题&#xff01; 原始表&#xff1a;employee_resignations表 employee_idresignation_date10012022-03-1510022022-11-2010032023-01-0510042023-07-1210052024-02-28 第一题&#xff1a; 查询累计到每个年度的离职人数 结果输出&#xff1a;年度、当年离职人数、累计…

工业RTOS生态重构:从PLC到“端 - 边 - 云”协同调度

一、引言 在当今数字化浪潮席卷全球的背景下&#xff0c;工业领域正经历着深刻变革。工业自动化作为制造业发展的基石&#xff0c;其技术架构的演进直接关系到生产效率、产品质量以及企业的市场竞争力。传统的PLC&#xff08;可编程逻辑控制器&#xff09;架构虽然在工业控制领…

从版本控制到协同开发:深度解析 Git、SVN 及现代工具链

前言&#xff1a;在当今软件开发的浪潮中&#xff0c;版本控制与协同开发无疑扮演着举足轻重的角色。从最初的单兵作战到如今大规模团队的高效协作&#xff0c;一套成熟且得力的版本控制系统以及围绕其构建的现代工具链&#xff0c;已然成为推动软件项目稳步前行的关键引擎。今…

Visual Studio Code插件离线安装指南:从市场获取并手动部署

Visual Studio Code插件离线安装指南&#xff1a;从市场获取并手动部署 一、场景背景二、操作步骤详解步骤1&#xff1a;访问官方插件市场步骤2&#xff1a;定位目标版本步骤3&#xff1a;提取关键参数步骤4&#xff1a;构造下载链接步骤5&#xff1a;下载与安装 三、注意事项 …

用HTML5实现实时ASCII艺术摄像头

用HTML5实现实时ASCII艺术摄像头 项目简介 这是一个将摄像头画面实时转换为ASCII字符艺术的Web应用&#xff0c;基于HTML5和原生JavaScript实现。通过本项目可以学习到&#xff1a; 浏览器摄像头API的使用Canvas图像处理技术实时视频流处理复杂DOM操作性能优化技巧 功能亮点…

论文审稿之我对SCI写作的思考

有幸被邀请审过二区、三区、四区期刊的论文&#xff0c;近期审稿10余篇&#xff0c;分享一下我从一个审稿人的角度出发&#xff0c;如何提升自己写作的质量。 作图高清和好看&#xff0c;永远是排第一位。图中的字要清晰&#xff0c;有的放大200%还看不清字&#xff1b;每幅图的…