翻譯|使用教程|編輯:吉煒煒|2025-01-16 13:29:38.140|閱讀 110 次
概述:雖然基于文本的比較方法很常見(jiàn),但在某些情況下,基于圖像的逐像素方法具有獨(dú)特的優(yōu)勢(shì)。本文探討了這種方法的適用情況和原因,并提供了突出其實(shí)用性和速度的示例和應(yīng)用程序。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門(mén)軟控件火熱銷(xiāo)售中 >>
相關(guān)鏈接:
文檔比較是許多行業(yè)中的關(guān)鍵功能,可幫助團(tuán)隊(duì)高效識(shí)別文檔版本之間的差異。雖然基于文本的比較方法很常見(jiàn),但在某些情況下,基于圖像的逐像素方法具有獨(dú)特的優(yōu)勢(shì)。本文提供了示例和應(yīng)用程序來(lái)展示此方法的實(shí)用性和速度,并探討了該方法何時(shí)以及為何有用。
使用 TX Text Control API,可以遍歷所有段落和字符以檢查位置和格式。雖然這在技術(shù)上是可行的,而且 TX Text Control 已經(jīng)很快了,但對(duì)于較長(zhǎng)的文檔來(lái)說(shuō),它還是太慢了。
TX Text Control 是一款功能類(lèi)似于 MS Word 的文字處理控件,包括文檔創(chuàng)建、編輯、打印、郵件合并、格式轉(zhuǎn)換、拆分合并、導(dǎo)入導(dǎo)出、批量生成等功能。廣泛應(yīng)用于企業(yè)文檔管理,網(wǎng)站內(nèi)容發(fā)布,電子病歷中病案模板創(chuàng)建、病歷書(shū)寫(xiě)、修改歷史、連續(xù)打印、病案歸檔等功能的實(shí)現(xiàn)。
基于圖像的文檔比較將文檔的頁(yè)面渲染為圖像,并逐個(gè)像素進(jìn)行比較。這種方法不是通過(guò)編程分析文本內(nèi)容、格式或定位,而是直接識(shí)別視覺(jué)差異。傳統(tǒng)的基于文本的比較方法解析文檔結(jié)構(gòu)、提取文本、分析格式并檢測(cè)位置差異。這個(gè)過(guò)程可能需要大量計(jì)算,尤其是對(duì)于布局復(fù)雜或格式繁雜的復(fù)雜文檔。基于圖像的比較跳過(guò)這些步驟并直接比較渲染的圖像,這可以大大縮短處理時(shí)間。
基于文本的方法可能會(huì)忽略某些視覺(jué)差異,例如輕微的字體變化、對(duì)齊偏移或顏色變化。逐像素比較可以準(zhǔn)確捕捉這些差異,使其成為視覺(jué)關(guān)鍵應(yīng)用的理想選擇。
為了演示目的,我們將使用 TX Text Control 安裝附帶的演示文檔。該文檔有六頁(yè),包含 TX Text Control 的大部分功能。
在第一遍中,我們將獲取文檔的兩個(gè)精確副本,并使用以下代碼對(duì)它們進(jìn)行比較。
using static DocumentComparer; | |
string document1 = "demo1.tx"; | |
string document2 = "demo2.tx"; | |
// Get the comparison results | |
List<PageComparisonResult> comparisonResults = DocumentComparer.CompareDocuments(document1, document2); | |
// Generate and display the results | |
foreach (var result in comparisonResults) | |
{ | |
if (result.PageIndex == -1) | |
{ | |
// Special case for differing page counts | |
Console.WriteLine(result.Message); | |
} | |
else | |
{ | |
string message = result.AreEqual | |
? $"The document images of page {result.PageIndex + 1} are equal." | |
: $"The document images of page {result.PageIndex + 1} are different."; | |
Console.WriteLine(message); | |
} | |
} |
運(yùn)行此代碼時(shí),結(jié)果將如下所示,這意味著文檔相同:
The document images of page 1 are equal. The document images of page 2 are equal. The document images of page 3 are equal. The document images of page 4 are equal. The document images of page 5 are equal. The document images of page 6 are equal.
現(xiàn)在讓我們改變第 1 頁(yè)第一段的字體,并縮小第 4 頁(yè)圖像的尺寸。
當(dāng)再次運(yùn)行相同的代碼時(shí),結(jié)果將如下所示:
The document images of page 1 are different. The document images of page 2 are equal. The document images of page 3 are equal. The document images of page 4 are different. The document images of page 5 are equal. The document images of page 6 are equal.
該類(lèi)DocumentComparer是一個(gè)靜態(tài)實(shí)用程序,用于逐頁(yè)比較兩個(gè)文檔。它可幫助您了解文檔在視覺(jué)上是否相同或存在差異。該CompareDocuments方法提供了比較兩個(gè)文檔的入口點(diǎn)。它使用服務(wù)器文本控件 實(shí)例加載兩個(gè)文檔,并將每個(gè)文檔轉(zhuǎn)換為位圖對(duì)象列表。
public static List<PageComparisonResult> CompareDocuments(string documentPath1, string documentPath2) | |
{ | |
var comparisonResults = new List<PageComparisonResult>(); | |
using (var serverTextControl = new ServerTextControl()) | |
{ | |
serverTextControl.Create(); | |
// Load and render the first document | |
serverTextControl.Load(documentPath1, StreamType.InternalUnicodeFormat); | |
var bitmapsDocument1 = GetDocumentImages(serverTextControl); | |
// Load and render the second document | |
serverTextControl.Load(documentPath2, StreamType.InternalUnicodeFormat); | |
var bitmapsDocument2 = GetDocumentImages(serverTextControl); | |
// Compare pages | |
if (bitmapsDocument1.Count != bitmapsDocument2.Count) | |
{ | |
comparisonResults.Add(new PageComparisonResult | |
{ | |
PageIndex = -1, | |
AreEqual = false, | |
Message = "The documents have different page counts." | |
}); | |
return comparisonResults; // Return early if page counts differ | |
} | |
for (int i = 0; i < bitmapsDocument1.Count; i++) | |
{ | |
using (var bitmap1 = bitmapsDocument1[i]) | |
using (var bitmap2 = bitmapsDocument2[i]) | |
{ | |
comparisonResults.Add(new PageComparisonResult | |
{ | |
PageIndex = i, | |
AreEqual = !DocumentComparer.IsDifferent(bitmap1, bitmap2), | |
Message = null | |
}); | |
} | |
} | |
} | |
return comparisonResults; | |
} |
每個(gè)位圖代表一個(gè)渲染頁(yè)面。該方法首先檢查文檔的頁(yè)數(shù)是否相同。如果頁(yè)數(shù)不同,它會(huì)立即返回一個(gè)結(jié)果,突出顯示此差異。對(duì)于頁(yè)數(shù)匹配的文檔,該方法使用 IsDifferent 函數(shù)比較每個(gè)頁(yè)面的渲染位圖對(duì)象,識(shí)別任何視覺(jué)差異。
該GetDocumentImages方法從加載到 ServerTextControl 的文檔中提取所有頁(yè)面的高分辨率圖像。每頁(yè)都以 300 DPI 呈現(xiàn),以保持高保真度并確保準(zhǔn)確的基于像素的比較。
private static List<Bitmap> GetDocumentImages(ServerTextControl serverTextControl) | |
{ | |
var bitmaps = new List<Bitmap>(); | |
var pages = serverTextControl.GetPages(); | |
for (int i = 1; i <= pages.Count; i++) | |
{ | |
// Get image for each page | |
bitmaps.Add(pages[i].GetImage(300, Page.PageContent.All)); | |
} | |
return bitmaps; | |
} |
該IsDifferent方法通過(guò)逐字節(jié)比較像素?cái)?shù)據(jù)來(lái)確定兩個(gè)位圖對(duì)象是否不同。如果圖像的尺寸不同,則立即將其標(biāo)記為不同。該方法鎖定像素?cái)?shù)據(jù)以實(shí)現(xiàn)高效訪(fǎng)問(wèn),逐字節(jié)比較原始像素?cái)?shù)據(jù)以查找不匹配,然后在比較完成后解鎖數(shù)據(jù)。這種方法可確保準(zhǔn)確檢測(cè)出細(xì)微的視覺(jué)差異。
public static bool IsDifferent(Bitmap bitmap1, Bitmap bitmap2) | |
{ | |
if (bitmap1 == null || bitmap2 == null) | |
{ | |
throw new ArgumentNullException("Bitmaps cannot be null."); | |
} | |
if (bitmap1.Width != bitmap2.Width || bitmap1.Height != bitmap2.Height) | |
{ | |
// Consider images different if dimensions are not the same. | |
return true; | |
} | |
// Lock the bits for both images for efficient pixel access. | |
var rect = new Rectangle(0, 0, bitmap1.Width, bitmap1.Height); | |
BitmapData data1 = bitmap1.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); | |
BitmapData data2 = bitmap2.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); | |
try | |
{ | |
// Compare pixel data byte by byte. | |
int bytes = data1.Stride * data1.Height; | |
byte[] buffer1 = new byte[bytes]; | |
byte[] buffer2 = new byte[bytes]; | |
System.Runtime.InteropServices.Marshal.Copy(data1.Scan0, buffer1, 0, bytes); | |
System.Runtime.InteropServices.Marshal.Copy(data2.Scan0, buffer2, 0, bytes); | |
for (int i = 0; i < bytes; i++) | |
{ | |
if (buffer1[i] != buffer2[i]) | |
{ | |
return true; | |
} | |
} | |
} | |
finally | |
{ | |
// Unlock the bits. | |
bitmap1.UnlockBits(data1); | |
bitmap2.UnlockBits(data2); | |
} | |
return false; | |
} |
基于 IImage 的文檔比較提供了一種獨(dú)特、非常快速且有效的方法來(lái)識(shí)別文檔之間的視覺(jué)差異。通過(guò)將文檔呈現(xiàn)為圖像并逐個(gè)像素進(jìn)行比較,此方法提供了一種快速而準(zhǔn)確的方法來(lái)檢測(cè)變化。這種方法對(duì)于視覺(jué)關(guān)鍵應(yīng)用程序特別有用,因?yàn)榛谖谋镜姆椒赡軙?huì)忽略細(xì)微的差異。該DocumentComparer實(shí)用程序演示了如何使用 TX Text Control 實(shí)現(xiàn)基于圖像的文檔比較,從而為比較文檔提供了一種實(shí)用且有效的解決方案。
產(chǎn)品試用下載、價(jià)格咨詢(xún)、優(yōu)惠獲取,或其他任何問(wèn)題,請(qǐng)聯(lián)系。
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:慧都網(wǎng)