public int LastPageNumber { get; set; }
An Int32 that indicates the 1-based index of the last page number in ImageFileName or ImageStream to recognize. You can use this and FirstPageNumber to recognize only a certain range of pages in the source file. You can use a value of -1 to indicate "up to last page in the file", otherwise, this member must be a value greater than or equal to FirstPageNumber up to the maximum number of pages in the source file name.
using Leadtools;using Leadtools.Codecs;using Leadtools.Ocr;using Leadtools.Document.Writer;using Leadtools.Forms.Common;using Leadtools.WinForms;public class RunJobExample{// Number of documents that are pendingprivate int _documentsPending;// Event to trigger when all documents are finishedprivate AutoResetEvent _allDocumentsFinishedEvent;public void Start(){string imagesDirectory = LEAD_VARS.ImagesDir;string documentsDirectory = Path.Combine(LEAD_VARS.ImagesDir, "RunJobExample");// Create the output (documents) directoryif (!Directory.Exists(documentsDirectory)){Directory.CreateDirectory(documentsDirectory);}// Get all TIF files in input (images) directorystring[] imageFileNames = Directory.GetFiles(imagesDirectory, "*.tif");if (imageFileNames.Length == 0){Console.WriteLine("No images to OCR");return;}// Create a new OCR engine instanceOcrEngineType engineType = OcrEngineType.LEAD;Console.WriteLine(string.Format("Starting up {0} engine", engineType));using (IOcrEngine ocrEngine = OcrEngineManager.CreateEngine(engineType)){ocrEngine.Startup(null, null, null, LEAD_VARS.OcrLEADRuntimeDir);// Setup document PDF save options: Image/Text with CCITT G4 encoding for B/WDocumentWriter docWriter = ocrEngine.DocumentWriterInstance;PdfDocumentOptions pdfOptions = docWriter.GetOptions(DocumentFormat.Pdf) as PdfDocumentOptions;pdfOptions.ImageOverText = true;pdfOptions.DocumentType = PdfDocumentType.Pdf;pdfOptions.FontEmbedMode = DocumentFontEmbedMode.None;pdfOptions.OneBitImageCompression = OneBitImageCompressionType.FaxG4;docWriter.SetOptions(DocumentFormat.Pdf, pdfOptions);// We are going to use multiple-threads, so disable threading in// IOcrAutoRecognizeManagerIOcrAutoRecognizeManager autoRecognizeManager = ocrEngine.AutoRecognizeManager;autoRecognizeManager.MaximumThreadsPerJob = 1;// Tell the recognize manager to continue on errorsautoRecognizeManager.JobErrorMode = OcrAutoRecognizeManagerJobErrorMode.Continue;// Instead of using events to trigger when documents are done,// we will use the JobCompleted events of IOcrAutoRecognizeManager// to decrement a counter and trigger one event when the counter reaches 0autoRecognizeManager.JobStarted += new EventHandler<OcrAutoRecognizeRunJobEventArgs>(autoRecognizeManager_JobStarted);autoRecognizeManager.JobCompleted += new EventHandler<OcrAutoRecognizeRunJobEventArgs>(autoRecognizeManager_JobCompleted);int count = imageFileNames.Length;_documentsPending = count;_allDocumentsFinishedEvent = new AutoResetEvent(false);for (int i = 0; i < count; i++){// Create the job datastring imageFileName = imageFileNames[i];string name = "Document " + (i + 1).ToString();Console.WriteLine("Queuing {0} file {1}", name, imageFileName);JobData data = new JobData();data.AutoRecognizeManager = autoRecognizeManager;data.ImageFileName = imageFileName;data.DocumentFileName = Path.Combine(documentsDirectory, Path.GetFileNameWithoutExtension(imageFileName) + ".pdf");data.JobName = name;// Queue this jobThreadPool.QueueUserWorkItem(new WaitCallback(RunJob), data);}// Wait for all documents to finish_allDocumentsFinishedEvent.WaitOne();_allDocumentsFinishedEvent.Close();autoRecognizeManager.JobStarted -= new EventHandler<OcrAutoRecognizeRunJobEventArgs>(autoRecognizeManager_JobStarted);autoRecognizeManager.JobCompleted -= new EventHandler<OcrAutoRecognizeRunJobEventArgs>(autoRecognizeManager_JobCompleted);Console.WriteLine("All documents finished, check the result files in {0}", documentsDirectory);}}private void autoRecognizeManager_JobStarted(object sender, OcrAutoRecognizeRunJobEventArgs e){// This is not strictly needed in this example, we will// use it to show informationConsole.WriteLine("{0} started...", e.Job.JobData.JobName);// Check if we need to abortif (AbortJobs(e.Job)){// Yes, abort all jobse.Job.AutoRecognizeManager.AbortAllJobs();}}private void autoRecognizeManager_JobCompleted(object sender, OcrAutoRecognizeRunJobEventArgs e){string message = string.Format("{0} completed ", e.Job.JobData.JobName);IOcrAutoRecognizeJob job = e.Job;// Show any errorsif (job.Errors.Count == 0){message += "successfully...";}else{message += "with errors, first error is " + job.Errors[0].Exception.Message;// And save the errors to a text file in the document directorystring documentFileName = job.JobData.DocumentFileName;string textPathName = Path.Combine(Path.GetDirectoryName(documentFileName), Path.GetFileNameWithoutExtension(documentFileName) + "_errors.txt");using (StreamWriter writer = File.CreateText(textPathName)){writer.WriteLine(job.JobData.JobName);writer.WriteLine("Data:");writer.WriteLine(" Image file name: " + job.JobData.ImageFileName);writer.WriteLine(" First page number: " + job.JobData.FirstPageNumber);writer.WriteLine(" Last page number: " + job.JobData.LastPageNumber);writer.WriteLine(" Format:" + job.JobData.Format);writer.WriteLine(" Document file name: " + job.JobData.DocumentFileName);writer.WriteLine("Errors:");foreach (OcrAutoRecognizeManagerJobError error in job.Errors){writer.WriteLine(" Page: {0} during {1}. Error: {2}", error.ImagePageNumber, error.Operation, error.Exception.Message);}}}Console.WriteLine(message);// Decrement the documents count, when we reach 0, we are done// Since this will be called from multiple threads, we need// to use a thread-safety procedureint pending = Interlocked.Decrement(ref _documentsPending);// If we are the last document, wait up main threadif (pending == 0){_allDocumentsFinishedEvent.Set();}}private class JobData{public IOcrAutoRecognizeManager AutoRecognizeManager;public string ImageFileName;public string DocumentFileName;public string JobName;}private void RunJob(object state){JobData data = state as JobData;Console.WriteLine("Running {0}", data.JobName);// Run itOcrAutoRecognizeJobData jobData = new OcrAutoRecognizeJobData(data.ImageFileName, DocumentFormat.Pdf, data.DocumentFileName);jobData.JobName = data.JobName;IOcrAutoRecognizeJob job = data.AutoRecognizeManager.CreateJob(jobData);data.AutoRecognizeManager.RunJob(job);}private bool AbortJobs(IOcrAutoRecognizeJob ocrJob){// In your application, you can check if abortion is required, for example, if the user// has pressed the Cancel button on a progress bar or if your service is shutting down.// In this example, we will never abort, but you can change this code to return true// upon any condition (or when a specific job is about to start)// and the engine will abort all current and pending jobsreturn false;}}static class LEAD_VARS{public const string ImagesDir = @"C:\LEADTOOLS22\Resources\Images";public const string OcrLEADRuntimeDir = @"C:\LEADTOOLS22\Bin\Common\OcrLEADRuntime";}