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.


Yet another way to create a mutable bitmap (Xamarin Android)


Current API provided by Android Bitmap doesn’t provide a constructor to create a mutable bitmap object, however you can make it mutable by copying the existing one with a mutable flag set.

Bitmap bitmap = new Bitmap(100, 100, Bitmap.Config.Argb8888);
Bitmap mutableBitmap = bm.Copy(Bitmap.Config.Argb8888, true);

Another way is to use a BitmapFactory and create bitmap object from stream or byte array with a mutable flag set.So for byte array it goes like this:

BitmapFactory.Options options = new BitmapFactory.Options();
options.InMutable = true;
options.InPreferredConfig = Bitmap.Config.Argb8888;
Bitmap result = BitmapFactory.DecodeByteArray(imageData, 0, imageData.Length, options);

But imageData is required to contain an encoded image not the raw pixel data. One of the solutions here that doesn’t require bitmap copying or reading from disk is to provide BitmapFactory with some data it’s able to recognize as an image and therefore decode.

The code

/// <summary>
/// A bitmap helper class by Apitron.
/// </summary>
static class BitmapHelper
    /// <summary>
    /// Creates mutable bitmap with ARGB32 pixel format.
    /// </summary>
    /// <param name="width">The width of the bitmap.</param>
    /// <param name="height">The height of the bitmap.</param>   
    /// <returns>Created bitmap.</returns>
    public static Bitmap CreateMutableBitmapARGB32(int width, int height)
        // pixel data
        uint pixelDataSize = (uint) (width*height*4);

        byte[] imageData = new byte[pixelDataSize+54];

        // "BM" +2
        imageData[0] = 0x42;
        imageData[1] = 0x4D;

        // bitmapsize +4; pixeldata size + bitmap file header(14 bytes) + bitmapinfo header(40 bytes)
        Array.Copy(BitConverter.GetBytes(pixelDataSize+54), 0, imageData, 2, 4);

        // reserved +4
        imageData[6] = 0;
        imageData[7] = 0;
        imageData[8] = 0;
        imageData[9] = 0;

        // pixel offset +4
        imageData[10] = 54;
        imageData[11] = 0;
        imageData[12] = 0;
        imageData[13] = 0;

        // header size offset +4
        imageData[14] = 40;
        imageData[15] = 0;
        imageData[16] = 0;
        imageData[17] = 0;

        // bitmapWidth +4
        Array.Copy(BitConverter.GetBytes(width), 0, imageData, 18, 4);

        // bitmapHeight +4
        Array.Copy(BitConverter.GetBytes(height), 0, imageData, 22, 4);

        // planes +2
        imageData[26] = 1;
        imageData[27] = 0;

        // bitcount +2
        imageData[28] = 32;
        imageData[29] = 0;

        // compression +4, BI_RGB
        imageData[30] = 0;
        imageData[31] = 0;
        imageData[32] = 0;
        imageData[33] = 0;

        // pixel data size +4
        Array.Copy(BitConverter.GetBytes(pixelDataSize), 0, imageData, 34, 4);

        // dpiX  +4
        Array.Copy(BitConverter.GetBytes(2835), 0, imageData, 38, 4);

        // dpiY +4
        Array.Copy(BitConverter.GetBytes(2835), 0, imageData, 42, 4);

        // clrUsed +4
        imageData[46] = 0;
        imageData[47] = 0;
        imageData[48] = 0;
        imageData[49] = 0;

        // clr important +4
        imageData[50] = 0;
        imageData[51] = 0;
        imageData[52] = 0;
        imageData[53] = 0;

        BitmapFactory.Options options = new BitmapFactory.Options();
        options.InMutable = true;
        options.InPreferredConfig = Bitmap.Config.Argb8888;
        Bitmap result = BitmapFactory.DecodeByteArray(imageData, 0, imageData.Length, options);
        result.HasAlpha = true;

        return result;

So it just creates a byte array sized to fit the requested bitmap data and adds BITMAPFILEHEADER and BITMAPINFOHEADER to make it look like an image in BMP format for BitmapFactory. Hope it will help someone looking for a mutable bitmap.


How to work with links in PDF documents


Many PDF documents can contain so-called Link Annotations (see PDF32000 specification, p.394, Link Annotations). For readers of the PDF document these objects may be presented as links to other pages within the same document or external destinations. Combined with bookmarks which are used to build a table of contents for PDF document, links help document authors to create a solid doc viewing experience.

When it comes to own PDF viewer implementation or if you just want to read whether there are any links on PDF page, Apitron PDF Rasterizer for .NET provides a uniform way to read, highlight or navigate using page links.

In short, a PDF Link Annotation object used to create a link is just a marker that defines which region of the page can interact with the used and trigger navigation. It doesn’t contain any text or other data except its “hot” region and target definition that in PDF terms is called Destination. But you don’t have to dive into the details of PDF format to use our API, because we provided a very clear and simple way to use this feature.

The code

Product package that you can download from our website contains the sample called LinksUsageSample, it demonstrates how to find all links on PDF page, highlight them using our product and render linked pages.

Assuming that you have stored current PDF page in variable named currentPage:

// enumerate through the page links collection and render linked pages
for(int i=0;i< currentPage.Links.Count;i++ )
    // try to navigate using given link and save linked page as bitmap
    if (document.Navigator.GoToLink(currentPage.Links[i]))
        // we use default PDF dpi settings for image as well as default rendering settings
        using (Bitmap bitmap = document.Navigator.CurrentPage.Render(new Resolution(72,72), settings))
            bitmap.Save(string.Format("{0}.png",i), ImageFormat.Png);


Highlight all links on PDF page:

private static void SavePageAsBitmapWithHightlightedLinks(Page page, RenderingSettings settings)
    int pageWidth = (int)page.Width;
    int pageHeight = (int)page.Height;

    // render page
    using (Bitmap bitmap = page.Render(pageWidth,pageHeight, settings))
        // create graphics object that we will use for drawing of the highlighting rects
        using (Graphics g = Graphics.FromImage(bitmap))
            using(Brush highlightBrush = new SolidBrush(Color.FromArgb(0x5FFFFF00)))
                foreach (Link link in page.Links)
                    Apitron.PDF.Rasterizer.Rectangle linkLocation = link.GetLocationRectangle(pageWidth,pageHeight,settings);

                    // PDF coordinate system has Y axis inverted in comparison to GDI, so transform the Y coordinate of the rect here
                    // because link object coordinates will be returned using PDF coordinate system.
                    g.FillRectangle(highlightBrush, new RectangleF((float) linkLocation.Left, pageHeight-(float) linkLocation.Top,(float) linkLocation.Width,(float) linkLocation.Height));

        bitmap.Save("Page_with_highlighted_links.png", ImageFormat.Png);

The result

Apitron PDF Rasterizer, page with highlighted links
Page with highlighted links

As it can be seen from the sample, getting all links from page and highlighting them is a quite simple task and you don’t have to write much code to do this using our component. 

If you take a look at the first piece of code you’ll notice that there we use document.Navigator property - it’s a part of build-in navigation mechanism and also can be used to navigate using bookmarks, search results, links, page indices, page instances or to get to the next our previous page of the document. 

It exposes DocumentNavigator object and is a must use for custom pdf viewer implementations. You can also read our other posts describing how to read pdf bookmarks (table of contents) and how to search text in PDF file.