Articles in this section
Category / Section

How to use Pdfium rendering engine with PdfViewer in Xamarin Forms and Android

6 mins read

By default, PdfViewer uses native Android PDF rendering. But, it also provides options in both Xamarin.Forms and Xamarin.Android platforms to use Pdfium that is a third party open source PDF rendering engine. Pdfium is the solution for overcoming defects in native Android rendering.     

 

Creating Pdfium binding library

 

To use Pdfium in your application, the Pdfium binding library is needed. A Pdfium binding library has already been created for your convenience and  is available with the demo sample attached at the bottom of this article.

The Pdfium binding project can also be created from scratch by following the steps below.

 

  1. Download the pdfium-android-1.7.0.aar android archive file from  https://mvnrepository.com/artifact/com.github.barteksc/pdfium-android/1.7.0

 

  1. To create the binding project from this archive file, refer to https://developer.xamarin.com/guides/android/advanced_topics/binding-a-java-library/binding-an-aar/

 

  1. Install the Xamarin.Android.Support.Compat dependency package in the project.

 

  1. Compile the project to generate the Pdfium library.

 

Using the Pdfium binding library in the application project

 

Refer to the binding library in your android project.   

Add a new class named “CustomPdfRenderer” to the android application project. This class must implement the ICustomPdfRenderer and ICustomPdfRendererService interfaces defined in the Syncfusion.SfPdfViewer.XForms.Droid and Syncfusion.SfPdfViewer.XForms namespaces respectively.

 

The entire CustomPdfRenderer class is given as follows.

C#

internal class CustomPdfRenderer : ICustomPdfRenderer, ICustomPdfRendererService 
    {
        internal PdfiumCore m_pdfiumCore;
        internal PdfDocument m_pdfDocument;
        internal int m_pageCount;
        internal Bitmap.Config m_bitmapConfig;
 
        /// <summary>
        /// Gets or sets the total page count of the PDF document
        /// </summary>
        public int PageCount
        {
            get
            {
                return m_pageCount;
            }
 
            set
            {
                m_pageCount = value;
            }
        }
        /// <summary>
        /// Gets or sets Bitmap.Config to render the bitmap from PDF document
        /// </summary>
        public Bitmap.Config BitmapConfig
        {
            get
            {
                return m_bitmapConfig;
            }
 
            set
            {
                m_bitmapConfig = value;
            }
        }
 
        /// <summary>
        /// Gets the dependency object of ICustomPdfRenderer 
        /// </summary>
        public object AlternatePdfRenderer
        {
            get
            {
                return this;
            }
        }
 
        /// <summary>
        /// Initializes the required object
        /// </summary>
        /// <param name="context">Context of the application</param>
        /// <param name="inputStream">PDF document stream</param>
        public void Initialize(Context context, Stream inputStream)
        {
            if (inputStream == null)
            {
                throw new System.NullReferenceException("object reference is not set to an instance: inputStream");
            }
            //Initializes the PdfiumCore instance
            m_pdfiumCore = new PdfiumCore(context);
            byte[] byteArray = ReadBytes(inputStream);
            if (m_pdfiumCore == null)
            {
                throw new System.NullReferenceException("object reference is not set to an instance: m_pdfiumCore");
            }
            //Creates the PdfDocument instance from the PDF byte array
            m_pdfDocument = m_pdfiumCore.NewDocument(byteArray);
            if (m_pdfDocument == null)
            {
                throw new System.NullReferenceException("object reference is not set to an instance: m_pdfDocument");
            }
            if (m_bitmapConfig == null)
            {
                m_bitmapConfig = Bitmap.Config.Rgb565;
            }
            //Gets the total number of pages from the PDF document
            m_pageCount = m_pdfiumCore.GetPageCount(m_pdfDocument);
        }
 
        /// <summary>
        /// Converts stream to byte array to render the PDF document using Pdfium renderer
        /// </summary>
        /// <param name="inputStream">PDF document stream to convert into byte array</param>
        /// <returns>byte array of PDF document</returns>
        private static byte[] ReadBytes(Stream input)
        {
            if (input.CanSeek)
            {
                input.Position = 0;
            }
            byte[] buffer = new byte[16 * 1024];
            using (MemoryStream ms = new MemoryStream())
            {
                int read;
                while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
                {
                    ms.Write(buffer, 0, read);
                }
                return ms.ToArray();
            }
        }
 
        /// <summary>
        /// Renders the PDF page as bitmap with specified page index
        /// </summary>
        /// <param name="bitmap">Bitmap to draw the content of the PDF page </param>
        /// <param name="pageIndex">Render the bitmap of PDF page with the page index</param>
        /// <param name="pageWidth">Width of the page to draw on to the bitmap</param>
        /// <param name="pageHeight">Height of the page to draw on to the bitmap</param>
        public void Render(Bitmap bitmap, int pageIndex, int pageWidth, int pageHeight)
        {
            if (bitmap == null)
            {
                throw new System.NullReferenceException("object reference is not set to an instance: bitmap");
            }
            if (m_pdfiumCore == null)
            {
                throw new System.NullReferenceException("object reference is not set to an instance: m_pdfiumCore");
            }
            else if (m_pdfDocument == null)
            {
                throw new System.NullReferenceException("object reference is not set to an instance: m_pdfDocument");
            }
            else if (pageIndex < 0 && pageIndex > m_pageCount - 1)
            {
                throw new System.ArgumentOutOfRangeException("pageIndex", "Index was out of range. Must be non-negative and less than the size of the PageCount.");
            }
            else
            {
               
                //Sets the config of Bitmap format we required to render the PDF pages
                bitmap.SetConfig(m_bitmapConfig);
                //Opens the PDF page with the specified page index to render the page as bitmap
                m_pdfiumCore.OpenPage(m_pdfDocument, pageIndex);
                m_pdfiumCore.RenderPageBitmap(m_pdfDocument, bitmap, pageIndex, 0, 0, pageWidth, pageHeight);
            }
        }
 
        /// <summary>
        /// Gets the Page size of the PDF document with given page index
        /// </summary>
        /// <param name="pageIndex">Page index to the get page size</param>
        /// <returns>Size of the page of PDF document </returns>
        public Android.Util.Size GetPageSize(int pageIndex)
        {
            if (m_pdfiumCore == null)
            {
                throw new System.NullReferenceException("object reference is not set to an instance: m_pdfiumCore");
            }
            else if (m_pdfDocument == null)
            {
                throw new System.NullReferenceException("object reference is not set to an instance: m_pdfDocument");
            }
            else if (pageIndex < 0 && pageIndex > m_pageCount - 1)
            {
                throw new System.ArgumentOutOfRangeException("pageIndex", "Index was out of range. Must be non-negative and less than the size of the PageCount.");
            }
            else
            {
                //opens the PDF page with specified index to get the Size of a Page
                m_pdfiumCore.OpenPage(m_pdfDocument, pageIndex);
                int pageHeight = m_pdfiumCore.GetPageHeightPoint(m_pdfDocument, pageIndex);
                int pageWidth = m_pdfiumCore.GetPageWidthPoint(m_pdfDocument, pageIndex);
                return new Android.Util.Size(pageWidth, pageHeight);
            }
        }
 
         /// <summary>
        /// Closes the initialized object to release memory
        /// </summary>
        public void Close()
        {
            //Closes the created PdfDocument instance
            m_pdfiumCore.CloseDocument(m_pdfDocument);
            //Disposes PdfiumCore instance
            m_pdfiumCore.Dispose();
        }
    }

 

The CustomPdfRenderer property should be assigned to the AlternatePdfRenderer property of the CustomPdfRenderer class.

C#

pdfViewer.CustomPdfRenderer = DependencyService.Get<ICustomPdfRendererService>().AlternatePdfRenderer;

 

Sample link:

https://www.syncfusion.com/downloads/support/directtrac/general/ze/PdfiumDemo1932199193


Conclusion

I hope you enjoyed learning how to use Pdfium rendering engine with PDF Viewer in Xamarin Forms Android.

You can refer to our Xamarin.Forms PDF Viewer feature tour page to know about its other groundbreaking feature representations and documentation, and how to quickly get started for configuration specifications.


For current customers, you can check out our components from the License and Downloads page. If you are new to Syncfusion, you can try our 30-day free trial to check out our other controls.

If you have any queries or require clarifications, please let us know in the comments section below. You can also contact us through our support forumsDirect-Trac, or feedback portal. We are always happy to assist you!

Did you find this information helpful?
Yes
No
Help us improve this page
Please provide feedback or comments
Comments (0)
Please sign in to leave a comment
Access denied
Access denied