獲取點擊點所在區域所能容納最大連續空白矩形面積及頂點坐標需求分析及相關解決方案

近日拿到一個需求,通過分析思考以及查詢資料得以解決,趁著不忙記錄一下:

需求:

頁面上放一個圖片控件,載入圖片之后,點擊圖片任何一個白色空間,找出點擊點所在區域所能容納的最大連續空白矩形面積及頂點坐標。

分析:

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
繁體地址,請注明出處:http://hk.pswp.cn/web/81263.shtml
英文地址,請注明出處:http://en.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;每幅圖的…