Articles in this section
Category / Section

How to use Pdfium rendering engine with PdfViewer in Xamarin Android

1 min read

By default, PdfViewer uses native Android PDF rendering to render the pages of the PDF document. It also provides options in both Xamarin.Forms Android and Xamarin.Android platforms to use Pdfium as an alternate, which is a third party open source PDF rendering engine. Using Pdfium rendering engine is the solution to overcome the defects in native Android PDF 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 and it is available with the demo sample attached at the bottom of this article for your convenience.

 

The Pdfium binding project can also be created from the scratch using 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 tohttps://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 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 interface defined in the Syncfusion.SfPdfViewer.Android namespace.

 

The entire CustomPdfRenderer class is given as follows.

C#

internal class CustomPdfRenderer : ICustomPdfRenderer
    {
        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>
        /// 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 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 in 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 render the content of the PDF page. </param>
        /// <param name="pageIndex">Index of the page in the PDF document being rendered.</param>
        /// <param name="pageWidth">Width of the page to be drawn on to the bitmap.</param>
        /// <param name="pageHeight">Height of the page to be drawn 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 size of the page with the provided index in the PDF document        /// </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 its Size
                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();
        }
    }

 

Create an instance of the CustomPdfRenderer class and assign it to the CustomPdfRenderer property of the PdfViewer.

 

C#

pdfViewer.CustomPdfRenderer = new CustomPdfRenderer();

 

Sample link:

http://www.syncfusion.com/downloads/support/directtrac/general/ze/PdfiumDemo-920917237 

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