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 layers - separate images, text, annotations, graphics

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

PDF to TIFF conversion
Contact us if you have a PDF related question and we'll cover it in our blog.

2014-05-11

Render PDF file using multiple threads (C# sample)

Once you've got your multicore machine, I bet you've been thinking about whether other tools are able to use these cores. Modern software should utilize every possibility to work faster and scale together with the system it’s designed for.

ApitronPDF Rasterizer was designed to get the most out of the .NET platform and also with ability to use as many CPU cores as its host system has. It was designed from the ground up to take advantage of multicore systems and parallel execution. Almost every operation that could benefit from it was parallelized.


The code


I've modified our sample included in product package in order to show you how the page by  page  PDF document rendering can be transformed to multithreaded. PDF specification was used as a test file.


/// <summary>
/// Render PDF file using ThreadPool
/// </summary>
private static void Main(string[] args)
{
    // open and load the file
    using (FileStream fs = new FileStream(@"..\..\..\Documents\pdf32000_2008.pdf", FileMode.Open))
    {
        // create rendering settings instance here, it can be used later for rendering cancellation if needed
        RenderingSettings renderingSettings = new RenderingSettings();

        // this object represents a PDF document
        Document document = new Document(fs);

        ManualResetEvent[] completionEvents = new ManualResetEvent[document.Pages.Count];

        // process and save pages one by one
        for (int i = 0; i < document.Pages.Count; i++)
        {
            int pageIndex = i;

            completionEvents[pageIndex] = new ManualResetEvent(false);

            ThreadPool.QueueUserWorkItem((state) =>
            {
                Page currentPage = document.Pages[pageIndex];

                // we use original page's width and height for image as well as default rendering settings
                using ( Bitmap bitmap = currentPage.Render( (int)currentPage.Width, (int)currentPage.Height, renderingSettings ))
                {
                    bitmap.Save(string.Format("{0}.png", pageIndex), ImageFormat.Png);
                }

                completionEvents[pageIndex].Set();
            });
        }

        // sync at this point and wait for all events to be set,
        // since WaitHandle.WaitAll supports only 64 handles we can't use it here
        foreach (ManualResetEvent manualResetEvent in completionEvents)
        {
            manualResetEvent.WaitOne();
        }

        // preview first rendered page
        Process.Start("0.png");
    }
}

Same code but using Tasks

/// <summary>
/// Render PDF file using Tasks
/// </summary>
private static void Main(string[] args)
{
    // open and load the file
    using (FileStream fs = new FileStream(@"..\..\..\Documents\pdf32000_2008.pdf", FileMode.Open))
    {
        // create rendering setting instance here, it can be used later for rendering cancellation if needed
        RenderingSettings renderingSettings = new RenderingSettings();

        // this object represents a PDF document
        Document document = new Document(fs);

        Task[] tasks = new Task[document.Pages.Count];

        // process and save pages one by one
        for (int i = 0; i < document.Pages.Count; i++)
        {
            int pageIndex = i;

            tasks[pageIndex] = new Task(()=>
            {
                Page currentPage = document.Pages[pageIndex];

                // we use original page's width and height for image as well as default rendering settings
                using (Bitmap bitmap = currentPage.Render((int)currentPage.Width, (int)currentPage.Height, renderingSettings))
                {
                    bitmap.Save(string.Format("{0}.png", pageIndex), ImageFormat.Png);
                }
            });

            tasks[pageIndex].Start();
        }

        // sync at this point and wait for all tasks to complete
        Task.WaitAll(tasks);

        // preview first rendered page
        Process.Start("0.png");
    }
}

Images


Start of the rendering, you clearly see how all 4 available CPU cores begin their work


Rendering begins


Rendering in progress, all cores are busy
Rendering in progress

Cancellation


While it’s important to perform multithreaded rendering it’s also important to handle rendering cancellation in most convenient and easy way.

Thread.Abort() usage is not a recommended approach, and  in case of Tasks even CancellationToken usage can only affect rendering that is not yet started. But we’ve designed our rendering engine to handle this situation and it’s possible to cancel rendering while it’s actually running. To do this just call CancelRendering() method using the RenderingSettings instance that was passed to rendering routine. And that’s it.

If you have any questions don’t hesitate to contact us and we’ll do our best to help you. As always we welcome any feedback.