public static void Example() { using (Xtractor.Xtractor xtractor = new Xtractor.Xtractor(filename: @"..\..\..\Input\Xtractor.Input.pdf")) { /* * PDF documents don't always store the desired reading order of the text. * Even if it does, the text is not required to be stored in the reading * order for that language. Some languages even have multiple acceptible * reading orders. Thus, Xtractor cannot guarantee getting text back in the * desired reading order for a given language. * * However, if you know what reading order you expect from your document, * it is still quite easy to get the desired result using LINQ. The example * below sorts the text for English, meaning top -> bottom first, * and left -> right second. */ Console.WriteLine("Extracting document text by reading order ..."); Xtractor.CharAndBox[] englishText = xtractor.ExtractTextWithLocation(pageNumber: 1, origin: Xtractor.Xtractor.CoordinateOrigin.BottomLeft); IEnumerable <Xtractor.CharAndBox> sortedText = englishText.OrderBy(cab => cab.Box.Y).ThenBy(cab => cab.Box.X); StringBuilder stringBuilder = new StringBuilder(); foreach (Xtractor.CharAndBox character in sortedText) { stringBuilder.Append(character.Character); } Console.WriteLine($"Document Text: {stringBuilder.ToString()}"); } }
public static void Example() { /* * Assume that you have a page with text that looks like this: * * --------------------------------- | | | North | | | | West Center East | | | | South | | | | --------------------------------- */ using (Xtractor.Xtractor xtractor = new Xtractor.Xtractor(filename: @"..\..\..\Input\Xtractor.Text.Location.pdf")) { //These functions have options to control which page you extract from, how many characters you want to get, //how far to the side of the original text in PDF units to search, and which instance on that page to use //as the reference point. string up = xtractor.ExtractTextAbove(pageNumber: 1, text: "Center", length: int.MaxValue, unitType: Xtractor.Xtractor.UnitType.Character); Console.WriteLine($"Text above center: {up.Trim()}"); string below = xtractor.ExtractTextBelow(pageNumber: 1, text: "Center", length: int.MaxValue, unitType: Xtractor.Xtractor.UnitType.Character); Console.WriteLine($"Text below center: {below.Trim()}"); string right = xtractor.ExtractTextRight(pageNumber: 1, text: "Center", length: int.MaxValue, unitType: Xtractor.Xtractor.UnitType.Character); Console.WriteLine($"Text right of center: {right.Trim()}"); string left = xtractor.ExtractTextLeft(pageNumber: 1, text: "Center", length: int.MaxValue, unitType: Xtractor.Xtractor.UnitType.Character); Console.WriteLine($"Text left of center: {left.Trim()}"); } }
public static void Example() { Console.WriteLine($"Counting number of pages in input document ..."); using (Xtractor.Xtractor xtractor = new Xtractor.Xtractor(filename: @"..\..\..\Input\Xtractor.Input.pdf")) { Console.WriteLine($" Number of pages found: {xtractor.PageTotal}."); } }
public static void Example() { // You have a few options, depending on how much detail you want. // Note that all of the "Xtractor.Xtractor.CoordinateOrigin" arguments are optional. using (Xtractor.Xtractor xtractor = new Xtractor.Xtractor(@"..\..\..\Input\Xtractor.Input.pdf")) { string searchPhrase = "ActivePDF"; // Gives back the bounding box of each occurrance of "ActivePDF" on page 1, // and results are relative to the top-left corner of the page. Console.WriteLine($"Retrieve the bounding box coordinates for all instances of {searchPhrase} on page one."); RectangleF[] page1BoundingBoxes = xtractor.FindText(text: searchPhrase, pageNumber: 1, origin: Xtractor.Xtractor.CoordinateOrigin.TopLeft); Console.WriteLine($"{page1BoundingBoxes.Length.ToString()} instance(s) of {searchPhrase} found on page 1."); foreach (RectangleF boundingBox in page1BoundingBoxes) { Console.WriteLine($" Box: ({boundingBox.X}, {boundingBox.Y}), ({boundingBox.X + boundingBox.Width}, {boundingBox.Y + boundingBox.Height})"); } Console.WriteLine(); // Gives back the bounding box of each occurrance of "ActivePDF" in the document. // Results are relative to the top-left corner of the page. // The first dimension of the array is sorted by page number, // so wholeDocumentBoundingBoxes[0] contains the same data as page1BoundingBoxes. Console.WriteLine($"Retrieve the bounding box coordinates for all instances of {searchPhrase} in the document."); RectangleF[][] wholeDocumentBoundingBoxes = xtractor.FindText(text: searchPhrase, origin: Xtractor.Xtractor.CoordinateOrigin.TopLeft); for (int i = 0; i < wholeDocumentBoundingBoxes.Length; ++i) { Console.WriteLine($"{wholeDocumentBoundingBoxes[i].Length.ToString()} instance(s) of {searchPhrase} found on page {i + 1}."); for (int j = 0; j < wholeDocumentBoundingBoxes[i].Length; ++j) { RectangleF boundingBox = wholeDocumentBoundingBoxes[i][j]; Console.WriteLine($" Box: ({boundingBox.X}, {boundingBox.Y}), ({boundingBox.X + boundingBox.Width}, {boundingBox.Y + boundingBox.Height})"); } } // Uses the regex @"\w+" to find all words on page 1. Gets back each word and location found. // Returned coordinates are given relative to the bottom left corner, in PDF units. Tuple <string, RectangleF>[] allWordsPage1 = xtractor.FindText(new Regex(@"\w+"), 1, Xtractor.Xtractor.CoordinateOrigin.BottomLeft); // Uses the regex @"\w+" to find all words in the document. Gets back each word and location found. // Returned coordinates are given relative to the bottom left corner, in PDF units. // allWordsWholeDocument[0] contains the same data as allWordsPage1. Tuple <string, RectangleF>[][] allWordsWholeDocument = xtractor.FindText(re: new Regex(@"\w+"), origin: Xtractor.Xtractor.CoordinateOrigin.BottomLeft); // Extracts the location of each individual character on page 1. Coordinates are relative to the top left corner. // The order of characters is in the PDF's order, which may or may not be in natural reading order. Xtractor.CharAndBox[] eachCharacterPage1 = xtractor.ExtractTextWithLocation(pageNumber: 1, origin: Xtractor.Xtractor.CoordinateOrigin.TopLeft); // Extracts the location of each individual character in the whole document. Coordinates are relative to the bottom left corner. // eachCharacterWholeDocument[0] contains the same characters in the same order as eachCharacterPage1, but the // coordinates returned will differ because they used different coordinate spaces when they were called. // Coordinates will match if they used the same coordinate space. // The order of characters is in the PDF's order, which may or may not be in natural reading order. Xtractor.CharAndBox[][] eachCharacterWholeDocument = xtractor.ExtractTextWithLocation(origin: Xtractor.Xtractor.CoordinateOrigin.BottomLeft); } }
public static void Example() { using (Xtractor.Xtractor xtractor = new Xtractor.Xtractor(filename: @"..\..\..\Input\Xtractor.Input.pdf")) { Xtractor.DocumentInfo xtractorDocInfo = xtractor.GetDocumentInfo(); WriteMetadata(XtractorDocInfo: xtractorDocInfo); Console.WriteLine(); WritePermissions(XtractorDocInfo: xtractorDocInfo); } }
public static void Example() { using (Xtractor.Xtractor xtractor = new Xtractor.Xtractor(filename: @"..\..\..\Input\Xtractor.Input.pdf")) { string searchTerm = "ActivePDF"; Console.WriteLine($"Counting search term, {searchTerm}, instances ..."); // Count instances on just the first page. int searchResults = xtractor.CountInstances(text: searchTerm, pageNumber: 1); Console.WriteLine($" Instances of {searchTerm} found on the first page: {searchResults}"); // Count instances in the entire document. searchResults = xtractor.CountInstances(text: searchTerm); Console.WriteLine($" Instances of {searchTerm} found in the document: {searchResults}"); } }
public static void Example() { // You have two options for extracting the page size. using (Xtractor.Xtractor xtractor = new Xtractor.Xtractor(filename: @"..\..\..\Input\Xtractor.Input.pdf")) { Console.WriteLine("Extracting document page dimensions ..."); // Extract the page size as two floats from page one. float width, height; xtractor.GetPageSize(pageNumber: 1, width: out width, height: out height); Console.WriteLine($" Page one Width: {width} Height: {height}"); // Extract the page size from page two as a rectangle. RectangleF pageSize = xtractor.GetPageSize(pageNumber: 2); Console.WriteLine($" Page two Width: {pageSize.Width} Height: {pageSize.Height}"); } }
public static void Example() { using (Xtractor.Xtractor xtractor = new Xtractor.Xtractor(filename: @"..\..\..\Input\Xtractor.Input.pdf")) { // This method extracts the text from pages, one page at a time. Console.WriteLine("Extract text from each page individually."); for (int pageNum = 1; pageNum <= xtractor.PageTotal; ++pageNum) { string pageText = xtractor.ExtractText(pageNumber: pageNum); Console.WriteLine($" Page {Convert.ToString(pageNum)} Text: {xtractor.ExtractText(pageNum)}"); } // This method extracts the text from the whole document at once. // The string[] is sorted by page number, where index 'n' is page 'n + 1'. string[] allTextArray = xtractor.ExtractText(); } }
public static void Example() { using (Xtractor.Xtractor xtractor = new Xtractor.Xtractor(filename: @"..\..\..\Input\Xtractor.Input.pdf")) { //Simple regex to search for all words. Regex re = new Regex(pattern: "\\w+"); Console.WriteLine($"Counting regular expression, {re.ToString()}, instances ..."); //Count instances on just the first page. int searchResults = xtractor.CountInstances(re: re, pageNumber: 1); Console.WriteLine($" Instances of {re.ToString()} found on the first page: {searchResults}"); //Count instances in the entire document. searchResults = xtractor.CountInstances(re: re); Console.WriteLine($" Instances of {re.ToString()} found in the document: {searchResults}"); } }
public static void Example() { using (Xtractor.Xtractor xtractor = new Xtractor.Xtractor(filename: @"..\..\..\Input\Xtractor.Input.pdf")) { //This saves the text from just page 1 to a file. xtractor.ExtractTextToFile(filename: @"..\..\..\Output\PageOneText.txt", pageNumber: 1); Process.Start(@"PageOneText.txt"); //This saves the text from the whole document to a file. xtractor.ExtractTextToFile(filename: @"WholeDocumentText.txt"); Process.Start(@"WholeDocumentText.txt"); //This overload contains an optional parameter for a string to insert //between the result of each page. It defaults to "\n". Each page may //contain newlines as well, so modify this if you need to be able to //tell pages apart. xtractor.ExtractTextToFile(filename: @"WholeDocumentTextPageBreak.txt", pageSeparationStr: "This is a page break."); Process.Start(@"WholeDocumentTextPageBreak.txt"); } }
public static void Example() { // Xtractor supports many image file formats, including jpg, png, tiff, and more. using (Xtractor.Xtractor xtractor = new Xtractor.Xtractor(filename: @"..\..\..\Input\Xtractor.Input.pdf")) { PointF location = new PointF(x: 50f, y: 50f); // On page 1, finds the image 50 units from the left edge, // and 50 units from the top, and saves to a jpg file. xtractor.ExtractImageToFile(filename: @"..\..\..\Output\ExtractImagesByLocation.jpg", pageNumber: 1, location: location, origin: Xtractor.Xtractor.CoordinateOrigin.TopLeft); // On page 1, finds the image 50 units from the left edge, // and 700 units from the bottom, and saves to a png file. xtractor.ExtractImageToFile(filename: @"..\..\..\Output\ExtractImagesByLocation.png", pageNumber: 1, location: new PointF(x: 50f, y: 700f), origin: Xtractor.Xtractor.CoordinateOrigin.BottomLeft); // Extracts the image 50 units from the left edge and 50 from the top of page 1, and returns it in memory. Bitmap imageAtLocation = xtractor.ExtractImage(pageNumber: 1, location: location, origin: Xtractor.Xtractor.CoordinateOrigin.TopLeft); imageAtLocation.Dispose(); } }
public static void Example() { using (Xtractor.Xtractor xt = new Xtractor.Xtractor(filename: @"..\..\..\Input\Xtractor.Input.pdf")) { // Saves all images on page 1 to bmp files. // The function will replace #PAGE# with the page number (1) and #NUM# with // the order it appeared on the page, starting at 1 and counting up. // The literal file names, after the #PAGE# AND #NUM# substitutions were made, are returned. // Using both #PAGE# and #NUM# are optional. string[] bmpFileNames = xt.ExtractImagesToFile(filenameOrMask: @"..\..\..\Output\#PAGE#_#NUM#.bmp", pageNumber: 1); foreach (string bmpFileName in bmpFileNames) { Process.Start(fileName: bmpFileName); } Console.WriteLine("First page BMP image processing complete, press any key to continue."); // Saves all images in the entire document to JPG files. string[] jpgFileNames = xt.ExtractImagesToFile(filenameOrMask: @"..\..\..\Output\#PAGE#_#NUM#.jpg"); foreach (string jpgFileName in jpgFileNames) { Process.Start(fileName: jpgFileName); } Console.WriteLine("JPG image processing complete, press any key to continue."); // Extracts all images on page 1, and returns them in memory. Bitmap[] allImagesPage1 = xt.ExtractImages(pageNumber: 1); // Process the images DisposeBitmaps(allImagesPage1); // Extracts all images in the whole document, and returns them in memory. // The first dimension in the array is sorted by page number in ascending order. // allImagesWholeDocument Bitmap[][] allImagesWholeDocument = xt.ExtractImages(); // Process the images DisposeBitmaps(allImagesWholeDocument); } }
public static void Example() { // When it comes to extracting bookmarks, you have two options. using (Xtractor.Xtractor xtractor = new Xtractor.Xtractor(filename: @"..\..\..\Input\Xtractor.Input.pdf")) { // Extract bookmarks as a JSON string. Console.WriteLine($"Extracting bookmarks as a JSON string."); string bookmarksJson = xtractor.GetBookmarksAsJson(); string bookmarksJonFile = "bookmarks.json"; using (FileStream outputStream = new FileStream(path: bookmarksJonFile, mode: FileMode.OpenOrCreate, access: FileAccess.ReadWrite)) { byte[] bookmarksBytes = Encoding.UTF8.GetBytes(s: bookmarksJson); outputStream.Write(array: bookmarksBytes, offset: 0, count: bookmarksBytes.Length); } Console.WriteLine($"Bookmark JSON data saved to: ${System.IO.Directory.GetCurrentDirectory()}\\{bookmarksJonFile}"); Console.WriteLine(); // Extract bookmarks as a tree structure. Console.WriteLine($"Extracting bookmarks as a tree structure."); Xtractor.DocumentOutline bookmarks = xtractor.GetBookmarksAsTree(); PrintBookmarks(bookmarks: bookmarks); } }
public static void Example() { using (Xtractor.Xtractor xtractor = new Xtractor.Xtractor(filename: @"..\..\..\Input\Xtractor.Input.pdf")) { // If you know where on the page you want to look, you can // restrict extractions to just that area. In this example, // we'll just a square 100 units on each side and pull from a // corner. const float boxWidth = 100, boxHeight = 810; for (int pageNum = 1; pageNum <= xtractor.PageTotal; ++pageNum) { // PDF allows each page to be a different size, so we should get the // page size for each page rather than once for the whole document. float pageWidth, pageHeight; xtractor.GetPageSize(pageNumber: pageNum, width: out pageWidth, height: out pageHeight); // We use Image Coordinates as the text origin [top left is (0, 0)] RectangleF topBox = new RectangleF(x: pageWidth - boxWidth, y: 0, width: boxWidth, height: boxHeight); string textTopRight = xtractor.ExtractTextWithin(pageNumber: pageNum, rect: topBox, origin: Xtractor.Xtractor.CoordinateOrigin.TopLeft); Console.WriteLine($"Top Right Text Page {pageNum}: {textTopRight}"); Console.WriteLine(); // or we can use PDF coordinates [bottom left is (0, 0)] RectangleF bottomBox = new RectangleF(x: pageWidth - boxWidth, y: boxHeight, width: boxWidth, height: boxHeight); string textBottomLeft = xtractor.ExtractTextWithin(pageNumber: pageNum, rect: bottomBox, origin: Xtractor.Xtractor.CoordinateOrigin.BottomLeft); Console.WriteLine($"Bottom Right Text Page {pageNum}: {textBottomLeft}"); Console.WriteLine(); } } }
public static void Example() { using (Xtractor.Xtractor xtractor = new Xtractor.Xtractor(@"..\..\..\Input\Xtractor.Input.pdf")) { // Simple Regex to search for numbers. Regex re = new Regex(pattern: "\\d+"); // Finds all the numbers on page 1. Console.WriteLine("Searching first page ..."); string[] page1Matches = xtractor.FindAllByRegex(re: re, pageNumber: 1); Console.WriteLine($"{page1Matches.Length} results found on page one."); Console.WriteLine(); // Finds all numbers in the whole document. The first dimension // of the array is sorted by page number. Console.WriteLine("Searching entire document ..."); string[][] wholeDocumentMatches = xtractor.FindAllByRegex(re: re); for (int i = 0; i < wholeDocumentMatches.Length; ++i) { Console.WriteLine($"{wholeDocumentMatches[i].Length} results found on page {i + 1}."); } } }
// This example contains different ways of opening an Xtractor input // file and how to handle passwords. public static void Example() { // Open a file from disk. using (Xtractor.Xtractor xtractor = new Xtractor.Xtractor(filename: @"..\..\..\Input\Xtractor.Input.pdf")) { // Perform your extractions here. Console.WriteLine("Successfully opened Xtractor.Input.pdf with Xtractor."); } //Open a file from memory. byte[] examplePDF = File.ReadAllBytes(@"..\..\..\Input\Xtractor.Input.pdf"); using (Xtractor.Xtractor xtractor = new Xtractor.Xtractor(file: examplePDF)) { // Perform your extractions here. Console.WriteLine("Successfully opened Xtractor.Input.pdf with Xtractor as a byte array."); } // Open a file with a password from disk. using (SecureString password = new SecureString()) { // We recommend never storing secure data like a password in a // 'string', however we will here for simplicity. string insecurePassword = "******"; foreach (char c in insecurePassword) { password.AppendChar(c); } password.MakeReadOnly(); using (Xtractor.Xtractor xtractor = new Xtractor.Xtractor(filename: @"..\..\..\Input\Xtractor.Input.Secure.pdf", password: password)) { // Perform your extractions here. Console.WriteLine("Successfully opened Xtractor.Input.Secure.pdf with Xtractor and input password."); } } // Open a file with a password from memory. examplePDF = File.ReadAllBytes(@"..\..\..\Input\Xtractor.Input.Secure.pdf"); using (SecureString password = new SecureString()) { string insecurePassword = "******"; foreach (char c in insecurePassword) { password.AppendChar(c); } password.MakeReadOnly(); using (Xtractor.Xtractor xtractor = new Xtractor.Xtractor(file: examplePDF, password: password)) { // Perform your extractions here. Console.WriteLine("Successfully opened Xtractor.Input.Secure.pdf with Xtractor as a byte array using a password."); } } // Handle an invalid password. // We aren't using a 'using' block here, like most other examples. // Since the runtime expands 'using' into a try/finally pattern anyway, we'll // manually expand it so we can add in a 'catch' as well. { Xtractor.Xtractor xtractor = null; try { string password = "******"; SecureString securePassword = new SecureString(); foreach (char c in password) { securePassword.AppendChar(c); } securePassword.MakeReadOnly(); xtractor = new Xtractor.Xtractor(filename: @"..\..\..\Input\Xtractor.Input.Secure.pdf", password: securePassword); // Perform your extractions here. Console.WriteLine("Successfully opened Xtractor.Input.pdf with Xtractor."); } catch (Xtractor.InvalidPasswordException) { // Handle the error here. Console.WriteLine("InvalidPasswordException caught opening Xtractor.Input.Secure.pdf"); } finally { xtractor?.Dispose(); } } }
static void Main(string[] args) { string appPath = System.AppDomain.CurrentDomain.BaseDirectory; string newPDF = "GeneratedPDF.pdf"; int result = -1; // Use Toolkit to create a new PDF using (APToolkitNET.Toolkit toolkit = new APToolkitNET.Toolkit()) { toolkit.OutputPageHeight = 792.0f; toolkit.OutputPageWidth = 612.0f; Console.WriteLine($"Toolkit: Generating new PDF using NewPage"); // Open the output file in memory result = toolkit.OpenOutputFile("MEMORY"); if (result != 0) { WriteResult($"Toolkit: Failed to open output file in-memory, error code {result}"); return; } // Each time a new page is required call NewPage toolkit.NewPage(); // Text can be added onto the new page with // SetFont, PrintText and PrintMultilineText functions toolkit.SetFont("Helvetica", 24); toolkit.PrintText(36.0f, 720.0f, $"Toolkit Version: {toolkit.ToolkitVersion}"); // Images can be added onto the new page with // PrintImage, PrintJPEG and PrintTIFF toolkit.PrintJPEG($"{appPath}IMG.jpg", 36.0f, 36.0f, 540.0f, 684.0f, true); // Close the new file to complete PDF creation toolkit.CloseOutputFile(); // Save the new PDF to the application path result = toolkit.SaveMemoryToDisk($"{appPath}{newPDF}"); if (result != 0) { WriteResult($"Toolkit: SaveMemoryToDisk failed, error code {result}"); return; } Console.WriteLine($"Toolkit: New pdf created {appPath}{newPDF}"); // Use Toolkit Compressor to compress images Console.WriteLine("Toolkit.Compressor: Compressing generated PDF"); toolkit.OpenOutputFile("MEMORY"); if (result != 0) { WriteResult($"Toolkit Compressor: Failed to open output file in-memory, error code {result}"); return; } // Retrieves the entire PDF as a string variable after you call // CloseOutputFile and set the output file name to MEMORY. toolkit.InputByteStream = toolkit.OutputByteStream; // Open the input file toolkit.OpenInputFile("MEMORY"); if (result != 0) { WriteResult($"Toolkit Compressor: Failed to open input file in-memory, error code {result}"); return; } // Instantiate the compressor object APToolkitNET.Compressor compressor = toolkit.GetCompressor(); // Compresses images in the output PDF with the default settings. compressor.CompressImages = true; result = toolkit.CopyForm(0, 0); if (result != 1) { WriteResult($"Toolkit Compressor: CopyForm failed, error code {result}"); return; } toolkit.CloseOutputFile(); // Save the compressed PDF to disk result = toolkit.SaveMemoryToDisk($"{appPath}Toolkit.Compressed.pdf"); if (result != 0) { WriteResult($"Toolkit Compressor: SaveMemoryToDisk failed, error code {result}"); return; } Console.WriteLine($"Toolkit Compressor: Compressed pdf created {appPath}Toolkit.Compressed.pdf"); } // Use Rasterizer to convert generated PDF to an image Console.WriteLine("\nRasterizer: Converting generated PDF to image format"); using (APRasterizerNET.Rasterizer rasterizer = new APRasterizerNET.Rasterizer()) { // Open PDF rasterizer.OpenFile($"{appPath}{newPDF}"); // Get page count of open file int pageCount = rasterizer.NumPages(); for (int currentPage = 1; currentPage <= pageCount; currentPage++) { // Image Format rasterizer.ImageFormat = APRasterizerNET.ImageType.ImgJPEG; // Output Type rasterizer.OutputFormat = APRasterizerNET.OutputFormatType.OutFile; // Other settings rasterizer.OutputFileName = $"{appPath}Rasterizer.ConvertPDFToJPEG.Page.{currentPage}.jpg"; // Render the current page rasterizer.RenderPage(currentPage); // Check for errors if (rasterizer.LastError != 0) { WriteResult($"Error rendering page {currentPage}: {rasterizer.LastErrorMessage}"); } Console.WriteLine($"Rasterizer: JPG image created at {appPath}Rasterizer.ConvertPDFToJPEG.Page.{currentPage}.jpg"); } } // Use Xtractor to extract text and images Console.WriteLine("\nXtractor: Extracting images and text from the generated PDF"); using (Xtractor.Xtractor xtractor = new Xtractor.Xtractor(filename: $"{appPath}{newPDF}")) { // Saves all images in the entire document to JPG files. string[] jpgFileNames = xtractor.ExtractImagesToFile(filenameOrMask: $"{appPath}Xtractor.#PAGE#_#NUM#.jpg"); Console.WriteLine($"Xtractor: Files extracted from \"{newPDF}\""); foreach (string file in jpgFileNames) { Console.WriteLine($"\tExtracted File: {file}"); } // This method extracts the text from the whole document at once. // The string[] is sorted by page number, where index 'n' is page 'n + 1'. string[] allTextArray = xtractor.ExtractText(); Console.WriteLine($"Xtractor: Text extracted from {newPDF}"); foreach (string text in allTextArray) { Console.WriteLine($"\tExtracted Text: {text}"); } } // Use Redactor to redact images and text from generated PDF Console.WriteLine("\nRedactor: Redacting images and text from the generated PDF"); using (APRedactor.Redactor redactor = new APRedactor.Redactor( filename: $"{appPath}{newPDF}")) { redactor.PageLiteralText = new string[] { "Version" }; redactor.TextMode = APRedactor.Redactor.TextRedactionMode.LiteralText; redactor.ImageMode = APRedactor.Redactor.ImageRedactionMode.Unconditional; int redactionsPerformed = redactor.Redact(); redactor.Save($"{appPath}RedactImagesAndText.pdf"); Console.WriteLine($"Redactor: Redacted PDF created {appPath}RedactedImagesAndText.pdf"); } WriteResult("\nSuccess!"); }