pdf links

PDF Rendering
Convert PDF to Image (.NET)
Convert PDF to image on Android (Xamarin)
Convert PDF to image on iOS (Xamarin)
Convert PDF to image in Windows Store apps (.NET)
Convert PDF to image in Windows Phone apps (.NET)
PDF to image in Universal Windows Store apps (.NET)
Free PDF Viewer control for Windows Forms (.NET)
How to integrate PDF Viewer control in WPF app (.NET)
Creating WPF PDF Viewer supporting bookmarks (.NET)
Cross-platform PDF Viewer using GTK# (MONO)
Silverlight PDF viewer control (Silverlight 5)
Multithreaded PDF rendering (.NET)
Convert pdf to image in Silverlight app (C# sample)
How to set fallback fonts for PDF rendering (C#)
Avoiding the out-of-memory exception on rendering (C#)
PDF viewer single page application (WebAPI, AngularJS)
PDF viewer control for Windows 10 universal applications
Use custom ICC profile for CMYK to RGB conversion

PDF Forms Creation PDF Security Conversion to PDF/A Other topics
PDF Document Manipulation PDF Content Generation
Fixed and Flow layout document API (.NET)
Creation of grids and tables in PDF (C# sample)
How to create interactive documents using Actions (C# sample)
Text flow effects in PDF (C# sample)
How to generate ordered and bulleted lists in PDF (C# sample)
Convert HTML to PDF using flow layout API (C# sample)
How to use custom fonts for PDF generation (.NET)
Create document with differently sized pages (C#)
Create PDF documents using MONO (C#/MONO/Windows/OSX)
How to use background images for content elements (C#/PDF Kit/FlowLayout)
Add transparent images to PDF document (C#)
Draw round rect borders in PDF documents(C#)
ICC color profiles and and ICC based colors in PDF (C#)
How to use bidirectional and right to left text in PDF (C#)
Create PDF documents from XML templates (C# sample)
How to resize PDF pages and use custom stamps (C#)
Add header and footer to PDF page (.NET sample)
How to use clipping mask for drawing on PDF page
Fill graphics path with gradient brushes in PDF (Shadings)
Apitron PDF Kit and Rasterizer engine settings
Add layers to PDF page (optional content, C# sample)
How to create free text annotation with custom appearance
PDF Content Extraction PDF Navigation
Contact us if you have a PDF related question and we'll cover it in our blog.

2016-11-30

Convert PDF to tiff using custom bitonal image conversion

Introduction

 

Sometimes default PDF to TIFF conversion doesn't provide the desired results, especially if it comes to black and white tiffs, containing so-called bitonal images. We've recently added a new mechanism into our Apitron PDF Rasterizer product which allows you to use custom bitonal image conversion implementation if you need it. See the sample below to see how it works.

The code

 

Provided code sample is a demo of custom bitonal conversion implementation and shows one of the possible ways to convert an RGB image to its black and white analog.

The idea is to scale the resulting image by the factory of 8 and put variably sized pixels consisting of black dots depending on the luminosity of  the source pixel. Thus one source pixel would correspond to a square formed by 64 black and white 1-bit pixels.

static void Main(string[] args)
{
    using (Stream inputStream = File.OpenRead("../../data/document.pdf"), 
        outputStream = File.Create("out.tiff"))
    {
        using (Document doc = new Document(inputStream))
        {
            doc.SaveToTiff(outputStream, new TiffRenderingSettings()
            {
                // set our conversion delegate
                ConvertToBitonal = MyConvertToBitonal
            });
        }
    }

    Process.Start("out.tiff");
}

private static byte[] MyConvertToBitonal(int width, int height, byte[] imageData, 
    out int resultingWidth, out int resultingHeight)
{
    // we will scale the resulting image,
    // each source pixel will correspond to 64 black and white pixels
    int scaleFactor = 8;
    resultingWidth = width * scaleFactor;
    resultingHeight = height * scaleFactor;

    // create resulting data buffer
    byte[] resultingImage = new byte[width * resultingHeight];
           
    double luminance;

    // black pixel goes first, lighter pixels follow
    byte[] pixel0 = new byte[] {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
    byte[] pixel1 = new byte[] {0x18, 0x3c, 0x7e, 0xFF, 0xFF, 0x7e, 0x3c, 0x18 };
    byte[] pixel2 = new byte[] {0, 0x18, 0x3c, 0x7e, 0x7e, 0x3c, 0x18, 0 };
    byte[] pixel3 = new byte[] {0, 0, 0x18, 0x3c, 0x3c, 0x18, 0, 0 };
    byte[] pixel4 = new byte[] {0, 0, 0, 0x18, 0x18, 0, 0, 0 };

           
    // iterate over the source pixels and modify bitonal image
    // according to own algorithm
    for (int y = 0, offsetY=0, stride=width*4; y < height; ++y, offsetY+=stride)
    {  
        // base offset for final pixel(s)
        int resultingPixelOffsetBase = y*width*scaleFactor;

        for (int x = 0, offsetX=0; x < width; ++x, offsetX+=4)
        {
            // read pixel data
            byte b = imageData[offsetY+offsetX];
            byte g = imageData[offsetY+offsetX+1];
            byte r = imageData[offsetY+offsetX+2];

            // calculate the luminance
            luminance = (0.2126*r + 0.7152*g + 0.0722*b);

            // based on the luminance we'll select which pixel to use
            // from the darkest one to the lightest
            if (luminance < 50)
            {
                SetPixel(resultingImage, resultingPixelOffsetBase+x, pixel0, width);
            }
            else if (luminance<100)
            {
                SetPixel(resultingImage, resultingPixelOffsetBase+x, pixel1, width);
            }
            else if(luminance <150)
            {
                SetPixel(resultingImage, resultingPixelOffsetBase+x, pixel2, width);
            }
            else if (luminance<200)
            {
                SetPixel(resultingImage, resultingPixelOffsetBase+x, pixel3, width);
            }
            else if (luminance < 250)
            {
                SetPixel(resultingImage, resultingPixelOffsetBase+x, pixel4, width);
            }
        }
    }

    return resultingImage;
}

/// Copies pixel data describing resulting pixel shape to the
/// resulting image
private static void SetPixel(byte[] resultingImage, int resultingPixelOffset, byte[] pixelData, 
int strideInBytes)
{
    for (int i = 0; i < pixelData.Length; ++i)
    {
        resultingImage[resultingPixelOffset + strideInBytes*i] = pixelData[i];
    }
}


The source file looks as follows:


Pic.1 Source PDF document
Pic. 1 Source PDF document

And the converted document is on the image below:

Converted bitonal tiff
Pic. 2 Converted bitonal tiff

If you zoom in you'll see that the image consists of variable black dots that create the smooth gradient fill:

 
Pic.3 Bitonal image
Pic. 3 Bitonal image

 

The complete code sample can be found in our github repo.

 

 Conclusion 

 

The Apitron PDF Rasterizer is a powerful and extensible cross platform library that can be used to handle all PDF rendering tasks with incredible ease and quality. If you have any questions just send us an email and we'll be happy to help you.

2016-10-20

Convert PDF to TIFF using custom rendering settings

Introduction


The task to convert from PDF to TIFF format can sometimes be tricky and quite challenging if you don’t have the right tool for that. Our Apitron PDF Rasterizer for .NET component has been offering this feature for years and now we’ve tweaked it a bit to fit into more demanding workflows. From now on, you’ll be able to control the conversion of the individual page by changing its DPI, rotation, crop and other parameters.

The complete code sample can be downloaded from our github repo.

 

The code


We’ll start with the following PDF document having one rotated page:

Pic. 1 Source PDF file before conversion to TIFF

Pic. 1 Source PDF file before conversion to TIFF


Using the custom page conversion handling code in the handler of BeforeRenderPage event, we’ll correct the rotation for the second page, set the crop and remove the 3d page.

internal class Program
{
    const int DPI = 144;

    private static void Main(string[] args)
    {
        // open and load the file
        using (FileStream fs = new FileStream(@"..\..\map.pdf", FileMode.Open),
             fsOut = File.Create("out.tiff"))
        {
            // this objects represents a PDF document
            using (Document document = new Document(fs))
            {
                // save to tiff using CCIT4 compression, black and white tiff.
                // set the DPI to 144.0 for this sample, so twice more than default PDF dpi setting.
               TiffRenderingSettings tiffRenderingSettings = 
                    new TiffRenderingSettings(TiffCompressionMethod.LZW, DPI, DPI);

                tiffRenderingSettings.RenderMode = RenderMode.HighQuality;
                tiffRenderingSettings.ScaleMode = ScaleMode.PreserveAspectRatio;
                tiffRenderingSettings.Compression = TiffCompressionMethod.LZW;

                // subscribe to before rendering event and adjust rendering settings 
                // for each page as you want 
                tiffRenderingSettings.BeforeRenderPage += TiffRenderingSettings_BeforeRenderPage;

                document.SaveToTiff(fsOut, tiffRenderingSettings);
            }

            System.Diagnostics.Process.Start("out.tiff");
        }
    }
         
    private static void TiffRenderingSettings_BeforeRenderPage(BeforeRenderPageEventArgs args)
    {
        // skip all pages expect first two
        if (args.PageIndex > 1)
        {
            args.IsPageSkipped = true;
            return;
        }

        // force the portrait mode for all pages if needed
        if (args.DesiredHeight < args.DesiredWidth)
        {
            args.RenderingSettings.RotationAngle = RotationAngle.Rotate270;
        }

        // crop from the all sides by cutting out existing margins
        double margin = 40;
        args.CropBox = new Rectangle(margin, margin, args.DesiredWidth - margin, 
              args.DesiredHeight - margin);
    }
}

The complete code sample can be found in our github repo and the resulting image is shown below:

Pic. 2 Cropped first page of the resulting TIFF file (gray area outlines its original dimensions)

Pic. 2 Cropped first page of the resulting TIFF file
(gray area outlines its original dimensions)

Produced tiff file will have only two cropped pages left as we ignored everything starting from the second one, and additionally the second page will be rotated for a better viewing.

Summary


The Apitron PDF Rasterizer for .NET component is a reliable and highly effective solution for those who need the ultimate quality and control over the PDF to image conversion. It can also be used for creation of cross-platform solutions targeting many platforms at once being available (including plain vanilla .NET) for Xamarin, Mono and Windows store based applications.

2016-09-15

Introduction to FDF or Forms Data Format



Introduction


All of you probably have seen or filled PDF forms while submitting tax reports, registration data and so on. PDF offers more than enough to support forms based workflow and to make data footprint smaller Adobe has introduced FDF – the Forms Data Format. 

Its purpose is isolate the data from the representation, meaning that FDF file doesn’t contain drawings, images and fonts which are typically used in “normal” PDF documents to display pages content, because it also doesn’t contain any pages as well (it’s not completely true because FDF annotations can contain graphical data, it will be covered later). It its simplest form a FDF document contains just a set of fields and their values. 

FDF can be used for submitting forms data to the server, receiving the response and filling the interactive forms. It can also be used for exporting PDF forms data to standalone files which can be stored in database or transmitted and later imported back to the original PDF form. Other features include adding custom annotations to the PDF document the FDF is applied to, or composing the PDF document from multiple sources using page templates.

So to summarize what you can do with FDF:

1) Export and import PDF forms data, you can have several interactive PDF forms templates sharing the same set of fields and use single FDF to fill all of them.

2) Add annotations, e.g. watermarks etc. to the target PDF documents

3) Import pages to PDF files from many source PDF documents, e.g. import document cover from one document and other parts from other documents. So you can even let your designers work in parallel on different templates and write code that combines them at the same time.

FDF is based on PDF and uses the same file structure, but has some differences described in section 12.7.7 Forms Data Format of the PDF specification. We prepared a set of code samples which show how to work with FDF using Apitron PDF Kit for .NET, you can find them below. The complete code sample can be downloaded from our github repo.



The code

 

How to generate FDF from PDF

 

We’ll be working with the following PDF form:

Pic. 1 Interactive PDF form


Pic. 1 Interactive PDF form


Here is the code for generating FDF from this PDF form using Apitron PDF Kit 

private static void GenerateFDF()
{
    using (Stream fileStream = File.Open("../../data/interactiveForm.pdf",
        FileMode.Open, FileAccess.ReadWrite))
    {
        using (FixedDocument target = new FixedDocument(fileStream))
        {
            // dump PDF doc's form data to FDF file
            using (FormsDataDocument fdfDocument = target.AcroForm.ExportFormsData())
            {
                using (FileStream fdfOutputStream = File.Create("interactiveForm.fdf"))
                {
                    fdfDocument.Save(fdfOutputStream);
                }
            }
        }
    }
}


You can also use Adobe Acrobat and go to Tools -> Forms -> More Form Options -> Manage Form Data -> Export Data… and save the results as FDF.


Fill PDF form using FDF


We’ll fill the same form using exported FDF file. As the originally the form was empty we will set several values to show how the FDF content can be altered on the fly.

private static void FillFormUsingLoadedFDF()
{
    using (Stream inputStream = File.Open("../../data/interactiveForm.pdf",
        FileMode.Open, FileAccess.ReadWrite), outputStream =File.Create("filledForm.pdf"))
    {
        // open the target PDF file
        using (FixedDocument target = new FixedDocument(inputStream))
        {
            // open the prepared FDF doc
            using (Stream fdfStream = File.Open("../../data/formData.fdf", FileMode.Open))
            {
                using (FormsDataDocument fdfDocument = new FormsDataDocument(fdfStream))
                {
                    // fill the FDF and apply it
                    fdfDocument.Fields["Name_First"].SetValue("John");
                    fdfDocument.Fields["Name_Last"].SetValue("Doe");
                    fdfDocument.Fields["Name_Middle"].SetValue("Middle");

                    target.ApplyFormsDataDocument(fdfDocument);
                }
            }

            target.Save(outputStream);
        }
    }
}

You can also simply open the FDF file in Adobe Reader to get it applied to the default PDF file  or use Tools -> Forms -> More Form Options -> Manage Form Data -> Import Data…


See the resulting document below:

Pic. 2 PDF form filled using FDF


Pic. 2 PDF form filled using FDF


Fill the PDF form using FDF created on the fly 

It’s easy to create FDF on the fly and apply to one or several PDF forms. Here we’ll apply generated FDF to the two different forms having the same set of fields.

private static void CreateFDFOnTheFlyAndFillForm(string pdfFormFile)
{
    using (Stream inputStream = File.Open(string.Format("../../data/{0}.pdf",pdfFormFile),
        FileMode.Open),
        outputStream = File.Create("filledForm.pdf"))
    {
        using (FixedDocument target = new FixedDocument(inputStream))
        {
            // create the forms data document and add
            // a few fields we know the names of along with their values.
            using (FormsDataDocument fdfDocument = new FormsDataDocument())
            {
                // add the first name field
                FdfField firstName = new FdfField("Name_First", FdfFieldType.Text);
                firstName.SetValue("John");

                // add the last name field
                FdfField lastName = new FdfField("Name_Last", FdfFieldType.Text);
                lastName.SetValue("Doe");

                // add the last name field
                FdfField middleName = new FdfField("Name_Middle", FdfFieldType.Text);
                middleName.SetValue("Alvanda");

                fdfDocument.Fields.Add(firstName);
                fdfDocument.Fields.Add(lastName);
                fdfDocument.Fields.Add(middleName);

                // apply the FDF doc to the target and save,
                // now we should have field's values copied to the
                // original PDF doc
                target.ApplyFormsDataDocument(fdfDocument);

                target.Save(outputStream);
            }
        }
    }
}

We’ll apply this code to the different versions of the same form, the normal one and compact. They both share the same set of fields and were created to show how the single FDF document can be used in “one data set” -> “many representations scenario”.

The normal filled form:

Pic. 3 The normal version of the form filled using FDF created on the fly


Pic. 3 The normal version of the form filled using FDF created on the fly


The compact version of the same form:

Pic. 4 Compact version of the PDF form filled using FDF created on the fly


Pic. 4 Compact version of the PDF form 
filled using FDF created on the fly

 

Add annotations using FDF


It’s possible to add annotations using FDF files and these annotations can contain drawings, text, images and other content allowed in regular PDF. One of the possible usage scenarios is separation of user-defined annotations and original PDF. This way you can always have the original version of the file and several sets or versions of annotations instead of saving several versions of the same PDF for every annotating session.

The code below shows how to add simple annotations using FDF:

private static void AddAnnotationsUsingFDF()
{
    // open pdf document that later can be used
    // as a target for applying FDF
    using (Stream inputStream = File.Open("../../data/interactiveForm.pdf", FileMode.Open),
        outputStream = File.Create("documentWithAnnotations.pdf"))
    {
        using (FixedDocument targetPDFDocument = new FixedDocument(inputStream))
        {
            // prepare our forms data document
            using (FormsDataDocument fdfDocument = new FormsDataDocument())
            {
                // set default file this document applies to
                fdfDocument.File = "interactiveForm.pdf";
                // add two annotations here, they will be added the target PDF document
                fdfDocument.Annotations.Add(new CircleAnnotation( 
                    new Boundary(100, 300, 300, 500),
                    AnnotationFlags.Default,
                    new AnnotationBorderStyle())
                {
                    Color = RgbColors.Red.Components,
                    InteriorColor = RgbColors.Yellow.Components,
                    Opacity = 0.5
                });

                fdfDocument.Annotations.Add(new TextAnnotation(190, 390)
                {
                    Contents = "A sample annotation created usign FDF!",
                    IsOpen = true
                });

                // optionally save the FDF, it can be opened later and used
                // for applying the content to PDF files
                using (FileStream fileStream = File.Create("annotations.fdf"))
                {
                    fdfDocument.Save(fileStream);
                }

                // Apply FDF and save the result. 
                // It can be also applied using Adobe PDF Reader,
                // just open it and it will be applied automatically using the file name
                // set to fdfDocument.File property.
                targetPDFDocument.ApplyFormsDataDocument(fdfDocument);

                targetPDFDocument.Save(outputStream);
            }
        }
    }
}
 
Resulting document looks as follows:

Pic. 5 Annotations added using FDF


Pic. 5 Annotations added using FDF


A more complex example shows how to add watermark with image to the PDF document.

private static void AddWatermarkUsingFDF()
{
    // open pdf document that later can be used
    // as a target for applying FDF
    using (Stream inputStream = File.Open("../../data/topSecretDocument.pdf", FileMode.Open),
        outputStream = File.Create("stampedAsTopSecret.pdf"))
    {
        using (FixedDocument targetPDFDocument = new FixedDocument(inputStream))
        {
            // prepare our forms data document
            using (FormsDataDocument fdfDocument = new FormsDataDocument())
            {
                // register image resource for future use
                fdfDocument.ResourceManager.RegisterResource(
     new Image("lock","../../data/lock.png",true));

                // set default file this document applies to
                fdfDocument.File = "topSecretDocument.pdf";

                double xOffsetFromLeft = 10;
                double yOffsetFromTop = 10;
                double contentHeight = 85;
                double contentWidth = Boundaries.Letter.Width - 20;

                // add watermark annotation here
                WatermarkAnnotation watermarkAnnotation =
                    new WatermarkAnnotation(
                        new Boundary(xOffsetFromLeft,
                           Boundaries.Letter.Height-yOffsetFromTop-contentHeight, 
                           xOffsetFromLeft+contentWidth,
                           Boundaries.Letter.Height-yOffsetFromTop ),
                           AnnotationFlags.Default,
                            new AnnotationBorderStyle());

                // generate custom content
                FixedContent annotationContent =   
                                          new FixedContent(Guid.NewGuid().ToString("N"),
new Boundary(0,0,watermarkAnnotation.Boundary.Width,
watermarkAnnotation.Boundary.Height));

                // create fixed size section
                Section section = new Section
                {
                    Border = new Border(1),
                    BorderColor = RgbColors.Red,
                    Width = contentWidth,
                    Height = contentHeight,
                    Padding = new Thickness(5),
                    LineHeight = 36,
                };

                // create text content
                TextBlock text = new TextBlock("TOP SECRET - AUTHORIZED PERSONNEL ONLY,
DESTROY THIS DOC AFTER READING.")
                {
                    Color = RgbColors.Red,
                    Font = new Apitron.PDF.Kit.Styles.Text.Font("Arial",26),
                    TextRenderingMode = TextRenderingMode.Stroke,
                    VerticalAlign = VerticalAlign.Middle
                };

                // add an image to the annotation's content,
                // set its float property to let the text flow.
                Image image = new Image("lock")
                {
                    Float = Float.Left
                };

                section.Add(image);
                section.Add(text);

                // set the content
                annotationContent.Content.AppendContentElement(section,
annotationContent.Boundary.Width,
annotationContent.Boundary.Height);
                watermarkAnnotation.Watermark = annotationContent;
                fdfDocument.Annotations.Add(watermarkAnnotation);

                // optionally save the FDF, it can be opened later and used
                // for applying the content to PDF files
                using (FileStream fileStream = File.Create("topSecretAnnotation.fdf"))
                {
                    fdfDocument.Save(fileStream);
                }

                // Apply FDF and save the result.
                // It can be also applied using Adobe PDF Reader,
                // just open it and it will be applied automatically using the the file name
                // set to fdfDocument.File property.
                targetPDFDocument.ApplyFormsDataDocument(fdfDocument);

                targetPDFDocument.Save(outputStream);
            }
        }
    }
}

The resulting document is shown below:

Pic. 6 Watermark added using FDF


Pic. 6 Watermark added using FDF


Insert pages to PDF documents using FDF and other PDFs as templates


FDF can be used as an intermediate link between the target PDF file and other PDFs acting as template sources for adding pages. Used this way the FDF will contain links to pages in other PDF documents making you able to assemble PDFs from many sources for particular purpose. You can even combine several pages from different files to one page if needed.

For it to work you should prepare source PDFs by marking desired pages as named templates. You can also define whether the template page can be visible or not for regular users. The image below shows how to set the page as template using Adobe Acrobat.

Pic. 7 Add page template using Adobe Acrobat


Pic. 7 Add page template using Adobe Acrobat

Alternatively you can do it in code, using Apitron PDF Kit:

// shows how to create PDF document and define page template
private static void CreatePDFDocumentAndSetTemplateName()
{
    // create PDF doc
    using (FixedDocument doc = new FixedDocument())
    {
        // create new page and add some content
        Page page = new Page();
        page.Content.Translate(10, 700);
        page.Content.AppendContentElement(
            new TextBlock(@"This page is used as a template in FDF document, its name is 'page1'.
                You can manage templates using Tools->Document Processing->Page Templates")
            { Color = RgbColors.Red }, 580, 100);

        doc.Pages.Add(page);
        // define the template by providing its name and page it refers to
        doc.Names.Pages.Add("page1",page);

        using (Stream stream = File.Create("templateSource.pdf"))
        {
            doc.Save(stream);
        }
    }
}

Here we just create the PDF file and add a named template to its visible templates collection (FixedDocument.Names.Pages). You can also create invisible template by adding the name and page to FixedDocument.Names.Templates collection. Having several source PDF files with defined templates we can create FDF document and use it to add all referenced pages to the target PDF document. See the code below:

private static void AddPagesUsingFDF()
{
    // create an empty PDF document (or you can an existing one)
    using (FixedDocument target = new FixedDocument())
    {
        // create and fill new FDF document
        using (FormsDataDocument fdfDoc = new FormsDataDocument())
        {
            // create template using first template source
            FdfNamedPageReference pageReference1 = new FdfNamedPageReference("page1",
                new FileSpecification("../../data/templateSource1.pdf"));
            FdfTemplate template1 = new FdfTemplate(pageReference1);

            // create template using second template source
            FdfNamedPageReference pageReference2 = new FdfNamedPageReference("page2",
                new FileSpecification("../../data/templateSource2.pdf"));
            FdfTemplate template2 = new FdfTemplate(pageReference2);

            // add pages based on templates created above
            fdfDoc.Pages.Add(new FdfPage(new[] {template1}));
            fdfDoc.Pages.Add(new FdfPage(new[] {template2}));
            // add combined page, its content is composed using several templates
            fdfDoc.Pages.Add(new FdfPage(new[] {template1, template2}));

            target.ApplyFormsDataDocument(fdfDoc);
        }

        using (Stream outputStream = File.Create("updatedDocumentWithAdditionalPages.pdf"))
        {
            target.Save(outputStream);
        }
    }
}

The resulting file contains 3 pages taken from: first PDF, second PDF and combined page composed used previous two. See the results below: 


Pic. 8 PDF file created by combining several files in FDF document, first page


Pic. 8 PDF file created by combining several files in FDF document, 
first page

 
Pic. 9 Combined PDF file, page 3 created by merging two templates into one page


Pic. 9 Combined PDF file, page 3 created by merging two templates
 into one page


 

Summary



In a highly loaded environment with lots of PDF forms to manage, one van clearly benefit from using FDF as the forms’ data storage. When it comes to assembling files from different sources, FDF sometimes may be simpler and also more convenient than other methods. It easily automates this task and can be used by end users as input for PDF processing applications. Apitron PDF Kit provides you with an ability to create and manage complex FDF and PDF documents using its easy to use and well-though API. 

It’s a cross-platform library and can be used to create apps targeting iOS and Android (via Xamarin) as well as Windows-based and MONO platforms. Contact us and we’ll be happy to answer your questions regarding our products and provide assistance if needed.