Tuesday, June 18, 2013

Convert PDF to image on iPhone, Xamarin iOS sample

Introduction

    In my previous post I described how to convert PDF file to image on Android device using Xamarin.Android.

    While Android is an extremely popular operating system nowadays, we can’t forget about another important player on this market – the iOS, and recent WWDC brought us to  iOS7, the os developers will be creating products for in upcoming year.


    Having the Xamarin, it’s now possible to create apps for both platforms sharing huge amount of code and saving time on support and maintenance, and we are going to show you how to use ApitronPDF Rasterizer for .NET and create your own PDF conversion app for iOS.

Getting ready

    If you are familiar with iOS development and Xamarin already, that’s great. But if you’re new to this world it might be useful to get the basic understanding of how it works.

    Here you can read about Xamarin - http://xamarin.com/monotouch And here you can find a “Hello, world” sample to start and play with http://docs.xamarin.com/guides/ios/getting_started/hello%2C_world

Checking out the rasterizer sample

Note: The sample assumes that you have Xamarin tools installed, I used Xamarin Studio on Mac and ran the sample on iPhone Simulator 6.1 device. It should work fine if you use MS Visual Studio though.

  1. Download the latest Apitron PDF Rasterizer package from here , unzip, navigate to Samples/IosSampleProject and open a corresponding project.
  2. Select iPhone Simulator 6.1 in devices menu and click Run
    Sample project opened in Xamarin Studio
  3. When iPhone simulator opens  you’ll see the app screen with brief description :
Main application screen

Click “Start rendering”. App starts PDF file conversion (the file is included into the Application Bundle for demo).

4. Once the conversion is finished you’ll see a notification message:

Finished processing


5. Press "Home"  and navigate to Photos, in Saved photos album you’ll see the resulting image:

Converted image preview


    That’s it! See “The Code” section below for code overview.

The code

Here is sample code that handles the button click event and does conversion:

// open a PDF file from app bundle
using(Stream stream  = File.OpenRead(Path.Combine(NSBundle.MainBundle.BundlePath,"testfile.pdf")))
{
    // construct the document
    Document doc = new Document (stream);
                    
    // we are going to render first page from the document
    Page page = doc.Pages [0];

    int w = (int)page.Width;
    int h = (int)page.Height;
             
    // render the page to a raw bitmap data represented by byte array
    byte[] imageData = ConvertBGRAtoRGBA(page.RenderAsBytes (w,h, new RenderingSettings (), null));

    // create CGDataProvider which will serve CGImage creation
    CGDataProvider dataProvider = new CGDataProvider (imageData, 0, imageData.Length);

    // create core graphics image using data provider created above, note that
    // we use CGImageAlphaInfo.Last(ARGB) pixel format
    CGImage cgImage = new CGImage(w,h,8,32,w*4,CGColorSpace.CreateDeviceRGB(),CGImageAlphaInfo.Last,dataProvider,null,falseCGColorRenderingIntent.Default);

   // create UIImage and save it to gallery
   UIImage finalImage = new UIImage (cgImage);

   finalImage.SaveToPhotosAlbum (null);

   // show notification message
   UIAlertView view = new UIAlertView ("Message",string.Format("Image has been saved to photo gallery"),null,"Ok",null);

   view.Show ();
}

Complete code can be found in [Component Package]\Samples\IosSampleProject folder.

Tuesday, June 11, 2013

PDF to image on Android, easy steps with Xamarin

      Let’s assume that you are developing an Android version of the already existing .NET application (desktop or web).And this application processes PDF files and saves them as images somewhere.

      I would personally look for a cross –platform solution that would reduce the amount of code I’d have to rewrite in order to target all these platforms.

      One of the solutions that could be easily found is to use Xamarin - a great project based on Mono and now becoming very popular for writing apps working on iOS, Mac, Windows and Android.

      That’s the base part, but I also need a library that works fine with Xamarin and can do PDF to image conversion. In my previous post  Creatingcross-platform PDF viewer using GTK# I demonstrated how we can create a simple application that shows PDF content on Windows and Mac OS X , and now it’s Android app’s turn.


So let’s follow step-by-step approach taken in previous posts and get this working.

STEP I - Setup

      Refer to the post Creatingcross-platform PDF viewer using GTK#  on how to setup environment, download latest Apitron PDF Rasterizer for .NET package and unzip it to the desired location. 

STEP II – Getting things built

       To make things simpler we provide a sample project called AndroidSample  that can be found in Samples folder inside the downloaded package. Open it using desired IDE, I will use MS VS.
       If everything is set up correctly project opens fine and builds without errors. If build fails, make sure that correct component dll is referenced. Remove the old reference and add new one, navigating to [Package_Folder]\ Microsoft.NET v2.0Android\Apitron.PDF.Rasterizer.dll.
                Otherwise it might be something wrong with environment setup, please read Xamarin documentation or post a comment here, I’ll try to help.

STEP III - Playground

       Ok, you’ve got it compiled! And now to make it more interesting, let’s not use the default PDF file provided with the sample (you may still use it, no problem, just hit Run). I’m going to add a new file, from
       For those decided to go this way, download the file by the link above and put in into Assets directory of the project, don’t forget to include it in project with AndroidAsset build action. Also  navigate to MainActivity.cs  and change button_click handler, replacing “testfile.pdf” to “3bigpreview.pdf”.

Build and hit Run, you should see the similar screen as below:



I used physical device connected to the PC, but you may want to run it on emulator also, to do it - click Start emulator image and run desired emulator.

So click OK and application deployment begins… once it’s finished, the application starts:



You see that application has very simple UI layout with just one button that says “Click me to start rendering”, let’s click it and see what happens.

Application starts processing the file that we have placed into its Assets folder, and when it finishes the following screen appears:


Done!

THE CODE


Here is the actual code that renders and saves image to storage, it is located in MainActivity.cs

// load the linked sample pdf file
using (Stream stream = Assets.Open("3bigpreview.pdf"), ms = new MemoryStream())
{
    stream.CopyTo(ms);

    ms.Position = 0;

    // create focument from the stream and request first page
    Document doc = new Document(ms);

    Page page = doc.Pages[0];

    // render the page using default settings
    int[] bitmapData = page.RenderAsInts((int)page.Width, (int)page.Height, new RenderingSettings());

    // convert given data to an android bitmap
    Bitmap bm = Bitmap.CreateBitmap(bitmapData, (int)page.Width, (int)page.Height, Bitmap.Config.Argb8888);

    // save image to device's gallery
    string imageUri = MediaStore.Images.Media.InsertImage(this.ContentResolver, bm, "MyImage", "An image created using Apitron.PDF.Rasterizer");

    // try to open the newly created image
    StartActivity( new Intent( Intent.ActionView,  Android.Net.Uri.Parse(imageUri)) );
}

Monday, June 10, 2013

Creating cross-platform PDF viewer using GTK#

Hi, having a bit of free time I decided to create a tiny sample that demonstrates how one of our products, the Apitron.PDF.Rasterizer for .NET can be used for cross-platform development.

Make sure you have the right environment set up. To get the sample working on Mac OS I've used Xamarin Studio, while my Windows PC has MS VS, Xamarin Studio and Mono & gtksharp package installed.

STEP I

Download latest component package from http://www.apitron.com/Downloads and unzip it to the desired location.

STEP II

Download the GTKViewer sample project from this location and open it with your IDE.
Add a reference to Apitron.PDF.Rasterizer.dll.

NOTE:
If you are trying it on Windows with Visual Studio I'd suggest to add the following line to your post-build steps(set the option Run the postbuild event: On Successful build):

"C:\Program Files (x86)\Mono-2.10.9\bin\mono.exe" $(TargetFileName)

it runs your app using mono after build, otherwise if you try to run it as usual BadImageFormatException will be thrown.

STEP III

Run the sample and select PDF file for viewing ( click File->Open), use arrows to navigate between pages.

The images below demonstrate the same application running on Mac OS X and Windows.

Mac OS X


Windows

Should you have any questions, please email me or post a comment. This example is quite simple but clearly demonstrates that cross-platform PDF processing is an easy task with right tools in hand.




Convert PDF to image (C# .NET sample)



Our .NET component Apitron PDF Rasterizer for.NET v.3.0  has been recently released and I’m going to show you how it can be used for PDF processing. 

STEP 1

Download component package from company website http://www.apitron.com/Downloads and unzip to desired folder.

STEP 2

Except folders for each framework version (it also has a specific build that works with Xamarin.Android – I plan additional post on how to use that) there is a Samples folder in unzipped directory containing several example projects. Go ahead and open ConvertPdfToImage.csproj.

I decided to go with my own file instead of default test PDF file provided with package and downloaded one from adobe website http://acroeng.adobe.com/Test_Files/viewing//3BigPreview.pdf and put in Samples\Documents folder.

The code is very simple but clearly demonstrates the process:

namespace ConvertPDFtoBitmap{
    using System.Diagnostics;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.IO;

    using Apitron.PDF.Rasterizer;
    using Apitron.PDF.Rasterizer.Configuration;

    internal class Program
    {
        private static void Main(string[] args)
        {
            // open and load the file
            using (FileStream fs = new FileStream(@"..\..\..\Documents\3BigPreview.pdf", FileMode.Open))
            {
                // this object represents a PDF document
                Document document = new Document(fs);
               
                // default rendering settings
                RenderingSettings settings = new RenderingSettings();

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

                    // 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,settings))
                    {
                        bitmap.Save(string.Format("{0}.png", i), ImageFormat.Png);
                    }
                }
                // preview first rendered page
                Process.Start("0.png");
            }
        }
    }
}


STEP 3

Enjoy the result:


This component can also be used for PDF to TIFF conversion, as well as reading PDF document properties like Author, Title or creation date.As you may see from the image above, advanced  CJK text rendering is nicely supported and many other drawing features that PDF specification describes.Patterns, shadings, images in various colorspaces, transparency..etc.