当前位置: 首页 > news >正文

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

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

需求:

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

分析:

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 查看!!!


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

相关文章:

  • k8s部署ELK补充篇:kubernetes-event-exporter收集Kubernetes集群中的事件
  • 【大模型面试每日一题】Day 28:AdamW 相比 Adam 的核心改进是什么?
  • STL 标准模板库全面解析:容器、算法与迭代器的核心应用
  • Linux学习心得问题总结(三)
  • 【工具变量】上市公司企业未来主业业绩数据集(2000-2023年)
  • CMake指令:find_package()在Qt中的应用
  • Collection集合遍历的三种方法
  • 大模型应用开发之RAG
  • leetcode106.从中序与后序遍历序列构造二叉树:索引定位与递归分治的完美配合
  • 网络 :序列和反序列化
  • 使用Docker Compose部署Dify
  • Linux `|` 管道操作符深度解析与高阶应用指南
  • SOC-ESP32S3部分:12-2、编码器驱动
  • ae卡通打架烟雾特效
  • 梯度下降 损失景观 视频截图
  • 第十八章:数据治理之数据质量:“数据质量”不仅仅和“数据质量”有关
  • 在train和eval模式下性能差距的问题(本文聚焦于BatchNorm2d)
  • 指针数组和数组指针的区别
  • ssm-ham项目1
  • 人工智能赋能教育:重塑学习生态,开启智慧未来
  • wordpress 中文版本/优化推广网站怎么做
  • 做旅游攻略比较好的网站/建站推广网站
  • 武汉汉口做网站价格/百度搜索风云榜总榜
  • 网站建设和app开发/网站怎么创建
  • 胶州建网站/武汉百度推广电话
  • 郑州电力高等专科学校专业有哪些/重庆seo公司怎么样