Compare PDFs
Printed From: Debenu Quick PDF Library - PDF SDK Community Forum
Category: For Users of the Library
Forum Name: I need help - I can help
Forum Description: Problems and solutions while programming with the Debenu Quick PDF Library and Debenu PDF Viewer SDK
URL: http://www.quickpdf.org/forum/forum_posts.asp?TID=3191
Printed Date: 26 Nov 24 at 5:09AM Software Version: Web Wiz Forums 11.01 - http://www.webwizforums.com
Topic: Compare PDFs
Posted By: tbean
Subject: Compare PDFs
Date Posted: 23 Oct 15 at 5:43PM
I need to compare PDFs to determine if a new PDF is a duplicate of one we already have received. Is there anything in the library that will allow me to compare two PDFs? Thanks, Tom
|
Replies:
Posted By: Ingo
Date Posted: 23 Oct 15 at 6:37PM
Hi Tom,
to be honest for this job you won't need the library. Read both documents into strings or streams and compare the strings/streams if there are differences. Or (still easier) check the file-lengths. Further jobs you can do with the library: Initiate a textextraction from both files and do a string-compare. Check the last modify-date from both files. There's a lot... Here's an older post regarding this issue: http://www.quickpdf.org/forum/pdf-comparison_topic2467.html
Cheers and welcome here, Ingo
------------- Cheers, Ingo
|
Posted By: tbean
Date Posted: 04 Nov 15 at 3:58PM
Ingo, I looked at the older post you provided and was able to find the duplicate using GetContentStreamToString() that you said in the other post returns the layout. Is comparing the results of GetContentStreamToString() more comprehensive than comparing those from GetPageText()? If I need to use GetPageText(), which ExtractOptions would be best? Thanks, Tom
|
Posted By: tbean
Date Posted: 04 Nov 15 at 4:39PM
Ingo, Another thing occurred to me. Which of these methods would be better if the PDF contains an image or will either of them work? Thanks, Tom
|
Posted By: tbean
Date Posted: 04 Nov 15 at 9:09PM
Ingo, Some of my PDFs are multi-page and when I call GetContentStreamToString(), I get back an array 27 bytes in length and GetPageText() returns an empty string. What do I need to do to get the content and text from a multi-page PDF? Thanks, Tom
|
Posted By: tbean
Date Posted: 06 Nov 15 at 6:16PM
Ingo, I found out GetContentStreamToString() returns an array 27 bytes in length and GetPageText() returns an empty string when the PDF was an image-only PDF. I added a call to HasFontResources() to determine if the PDF is image-only and don't make calls to GetContentStreamToString() and GetPageText() if it is image-only. Is HasFontResources() the best way to determine if the PDF is image-only? Since I can't compare the images, I assume the PDFs are different. Thanks, Tom
|
Posted By: Ingo
Date Posted: 08 Nov 15 at 8:22PM
Hi Tom,
GetContentStream analyses the content of the page. The content will be more than just text ;-)
If two pdf-files are image-only you'll find differences in the result of the two GetContentStream-calls. Yes: HasFontResources is a good function to check if the document is image-only.
With this code (without using the library) you can always see if there are differences:
// ... textcomplete : WideString; // ... try textcomplete := TFile.ReadAllText(Edit1.Text); // c:\temp\test.pdf except { Catch the possible exceptions MessageDlg('Incorrect path', mtError, [mbOK], 0); Exit; } end; // ...
Cheers, Ingo
------------- Cheers, Ingo
|
Posted By: tbean
Date Posted: 11 Nov 15 at 7:07PM
Ingo, My code is written in C# so I tried using File.ReadAllText() but the resulting text didn't contain any of the data from the PDF. Below are a few lines from the text. When I tried using GetPageText(), the only data it returned was the static text of the form and none of the data in the fields. The form was a fillable PDF that I had flattened. When I tried opening it in Adobe LiveCycle Designer, I got an error saying no fields could be found. Is there some other method I can use to get the field data? Would it be possible for me to upload the text file and the PDF document for you to take a look at? Thanks, Tom --------------------- %PDF-1.6 %���� 192 0 obj << >> endobj 190 0 obj
|
Posted By: Ingo
Date Posted: 11 Nov 15 at 11:03PM
Hi Tom,
yes... you can upload it anywhere and then you can post the link here. Then perhaps one of us here (user community) or me myself will have a look.
Cheers, Ingo
------------- Cheers, Ingo
|
Posted By: tbean
Date Posted: 12 Nov 15 at 5:03PM
Ingo, I zipped both the PDF and the extracted text file. They are at: http://www.filedropper.com/pdf_9" rel="nofollow - http://www.filedropper.com/pdf_9 . Thanks, Tom
|
Posted By: tbean
Date Posted: 18 Nov 15 at 4:46PM
Ingo, I tried the link today and it didn't work so I uploaded the file again. Please try it now and you should be able to download the file. Thanks, Tom
|
Posted By: Ingo
Date Posted: 23 Nov 15 at 9:17PM
Hi Tom,
link doesn't work.
Cheers, Ingo
------------- Cheers, Ingo
|
Posted By: tbean
Date Posted: 23 Nov 15 at 9:31PM
Ingo, I just uploaded it again, now the link is: http://www.filedropper.com/pdf_8" rel="nofollow - http://www.filedropper.com/pdf_8 Tom
|
Posted By: Ingo
Date Posted: 24 Nov 15 at 8:46PM
Hi Tom,
there's no problem extracting the textcontent. The extract starts with "CERTIFICATE OF LIABILITY INSURANCE". Formfields will be extracted, too. You can see it at content like this: "AUTOMOBILE LIABILITY X".
I've checked the file with my tool. The pdf was a form and after filled out it was flattened. But still there's one real formfield... Strange?
But you're telling us that you can't extract the textcontent and this shouldn't happen. Please post your code here. You should start with creating the instance und you should end with freeing the instance. I'm pretty sure that here's somebody telling you where's something wrong with the code ;-)
Cheers, Ingo
------------- Cheers, Ingo
|
Posted By: tbean
Date Posted: 24 Nov 15 at 9:03PM
Ingo, My code is below. Tom ---------------------------- public static bool GetPDFContent(byte[] pdfData, ref byte[] pdfContent, ref string pdfText) { if (pdfData.Length > 0)
{
try
{
ClearPDFLibrary();
pdfContent = new byte[0];
pdfText = string.Empty;
byte[] pageBytes;
pdfData = FlattenPDF(pdfData);
// Load PDF Document
pdfLibrary.LoadFromString(pdfData, "");
// if the PDF has no fonts, it is an image only PDF
if (pdfLibrary.HasFontResources() == 0)
{
return false;
}
int documentId = pdfLibrary.SelectedDocument(); // get the document id
int count = pdfLibrary.PageCount();
int index = 1;
while (index <= count)
{
int newDocumentId = pdfLibrary.NewDocument(); // create new document (has an empty page)
pdfLibrary.CopyPageRanges(documentId, index.ToString()); // copy page to new document
// delete the empty page
pdfLibrary.DeletePages(1, 1);
pdfLibrary.SelectPage(1);
pdfLibrary.SelectContentStream(1);
// get the content of each page and append them to pageBytes
pageBytes = pdfLibrary.GetContentStreamToString();
Array.Resize(ref pdfContent, pdfContent.Length + pageBytes.Length);
Buffer.BlockCopy(pageBytes, 0, pdfContent, pdfContent.Length - pageBytes.Length, pageBytes.Length);
// get the text of each page and concatenate them to pdfText
pdfText += pdfLibrary.GetPageText(0);
// remove the new document
pdfLibrary.RemoveDocument(newDocumentId);
++index;
}
// remove the original document
pdfLibrary.RemoveDocument(documentId);
}
catch (Exception ex)
{
ExceptionLog exceptionLog = new ExceptionLog(ERCPDFApplication, ERCPDFUser, ex);
exceptionLog.Commit();
return false;
}
}
return true; }
|
Posted By: Ingo
Date Posted: 24 Nov 15 at 9:14PM
Hi Tom,
i don't know the language but i think the problem is already at the beginning. What's inside pdfData? How and where you get these content?
In Pascal/Delphi you'll need something similar to this one: // ... try QP := TDebenuPDFLibrary1114.Create; try ret1 := QP.UnlockKey'your_reg_key'); ret2 := QP.LoadFromFile(FName.Text, ''); // ...
Perhaps the other guys here can better give better help?
Cheers, Ingo
------------- Cheers, Ingo
|
Posted By: tbean
Date Posted: 24 Nov 15 at 9:47PM
Ingo, pdfData is a byte array with the contents of the PDF. I get the PDF data from our database and use LoadString() to load it into the PDFLibrary, so, it's equivalent to LoadFromFile(). Regards, Tom
|
Posted By: Ingo
Date Posted: 25 Nov 15 at 8:24PM
Hi Tom,
why you're doing FlattenPDF before the LoadFromString? I think this won't work... Is the += okay in these programming language? pdfText += pdfLibrary.GetPageText(0);
You should make your function smaller getting a better overview and try again. Try textextraction first without the other stuff. Only LoadFromString, SelectPage and Extraction ...
Cheers, Ingo
------------- Cheers, Ingo
|
Posted By: tbean
Date Posted: 25 Nov 15 at 10:03PM
Ingo, I only added the FlattenPDF call after I encountered the problem with no field data being found for a couple of documents like the one I uploaded. When we received this document it was fillable and I thought maybe that was the reason no field data was found. The C# operator += is used to append the data of the variable on the right to the variable on the left. It is equivalent to "pdfText = pdfText + pdfLibrary.GetPageText(0);". Regards, Tom
|
Posted By: Ingo
Date Posted: 25 Nov 15 at 10:30PM
as i've written: Remove all stuff and start again small with LoadFromString, SelectPage, ExtractPage, ... If this run than step by step go on...
Cheers, Ingo
------------- Cheers, Ingo
|
|