46

I need to convert PDFfile(PDF page) into a Bitmap(or Image file) in Android.

1.Used Pdfbox jar from Apache. But it uses some java classes that is not supported in android. 2. Tried Itext jar which converts image to pdf(I need its reverse operation) Like that I have tried many jars. But no positive result.

byte[] bytes; try { File file = new File(this.getFilesDir().getAbsolutePath()+"/2010Q2_SDK_Overview.pdf"); FileInputStream is = new FileInputStream(file); // Get the size of the file long length = file.length(); bytes = new byte[(int) length]; int offset = 0; int numRead = 0; while (offset < bytes.length && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) { offset += numRead; } ByteBuffer buffer = ByteBuffer.NEW(bytes); String data = Base64.encodeToString(bytes, Base64.DEFAULT); PDFFile pdf_file = new PDFFile(buffer); PDFPage page = pdf_file.getPage(2); RectF rect = new RectF(0, 0, (int) page.getBBox().width(), (int) page.getBBox().height()); // Bitmap bufferedImage = Bitmap.createBitmap((int)rect.width(), (int)rect.height(), // Bitmap.Config.ARGB_8888); Bitmap image = page.getImage((int)rect.width(), (int)rect.height(), rect); FileOutputStream os = new FileOutputStream(this.getFilesDir().getAbsolutePath()+"/pdf.jpg"); image.compress(Bitmap.CompressFormat.JPEG, 80, os); // ((ImageView) findViewById(R.id.testView)).setImageBitmap(image); 

I am getting the Image File, enter image description here

Instead of, enter image description here

package com.test123; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import com.sun.pdfview.PDFFile; import com.sun.pdfview.PDFPage; import net.sf.andpdf.nio.ByteBuffer; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.RectF; import android.os.Bundle; import android.util.Base64; public class Test123Activity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); byte[] bytes; try { File file = new File(this.getFilesDir().getAbsolutePath()+"/2010Q2_SDK_Overview.pdf"); FileInputStream is = new FileInputStream(file); // Get the size of the file long length = file.length(); bytes = new byte[(int) length]; int offset = 0; int numRead = 0; while (offset < bytes.length && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) { offset += numRead; } ByteBuffer buffer = ByteBuffer.NEW(bytes); String data = Base64.encodeToString(bytes, Base64.DEFAULT); PDFFile pdf_file = new PDFFile(buffer); PDFPage page = pdf_file.getPage(2); RectF rect = new RectF(0, 0, (int) page.getBBox().width(), (int) page.getBBox().height()); // Bitmap bufferedImage = Bitmap.createBitmap((int)rect.width(), (int)rect.height(), // Bitmap.Config.ARGB_8888); Bitmap image = page.getImage((int)rect.width(), (int)rect.height(), rect); FileOutputStream os = new FileOutputStream(this.getFilesDir().getAbsolutePath()+"/pdf.jpg"); image.compress(Bitmap.CompressFormat.JPEG, 80, os); //((ImageView) findViewById(R.id.testView)).setImageBitmap(image); } catch (Exception e) { e.printStackTrace(); } } } 

Else, any other way to display pdf file in android using function inbuilt within application?

16
  • We can convert the pdf to image using awt tools in java.but awt is not supported by android.i am also using itext..if u know python u can convert pdf to bitmap using ghostscript. Commented Jan 11, 2012 at 6:03
  • I dont know python.. Is there any way to do it in java? Commented Jan 11, 2012 at 6:19
  • Please see the above code.. I have used the jar from the link, github.com/jblough/Android-Pdf-Viewer-Library/blob/master/… I able to convert the PDFpage into jpg file. But the converted image is partially converted. I dont know where I am wrong? Commented Jan 11, 2012 at 6:25
  • what is the code u r giving?is this working? Commented Jan 11, 2012 at 6:31
  • Its working in the sense, I am getting the first image instead of second one. Commented Jan 11, 2012 at 6:38

7 Answers 7

29

I solved this issue. it's as simple as letting the device have time to render each page.

To fix this all you have to do is change

PDFPage page = pdf_file.getPage(2); 

to

PDFPage page = pdf_file.getPage(2, true); 

Firstly to view a PDF in Android you have to convert the PDF into images then display them to the user. (I am going to use a webview)

So to do this we need this library. It is my edited version of this git.

After you have imported the library into your project you need to create your activity.

The XML:

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <WebView android:id="@+id/webView1" android:layout_width="match_parent" android:layout_height="match_parent"/> </LinearLayout> 

The java:

//Imports: import android.app.Activity; import android.app.ProgressDialog; import android.content.Intent; import android.graphics.Bitmap; import android.os.AsyncTask; import android.os.Bundle; import android.os.Environment; import android.util.Base64; import android.util.Log; import android.view.View; import android.view.ViewTreeObserver; import android.webkit.WebView; import com.sun.pdfview.PDFFile; import com.sun.pdfview.PDFImage; import com.sun.pdfview.PDFPage; import com.sun.pdfview.PDFPaint; import net.sf.andpdf.nio.ByteBuffer; import net.sf.andpdf.refs.HardReference; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.RandomAccessFile; import java.nio.channels.FileChannel; //Globals: private WebView wv; private int ViewSize = 0; //OnCreate Method: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //Settings PDFImage.sShowImages = true; // show images PDFPaint.s_doAntiAlias = true; // make text smooth HardReference.sKeepCaches = true; // save images in cache //Setup webview wv = (WebView)findViewById(R.id.webView1); wv.getSettings().setBuiltInZoomControls(true);//show zoom buttons wv.getSettings().setSupportZoom(true);//allow zoom //get the width of the webview wv.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { ViewSize = wv.getWidth(); wv.getViewTreeObserver().removeGlobalOnLayoutListener(this); } }); try { File file = new File(Environment.getExternalStorageDirectory().getPath() + "/randompdf.pdf"); RandomAccessFile f = new RandomAccessFile(file, "r"); byte[] data = new byte[(int)f.length()]; f.readFully(data); pdfLoadImages(data); } catch(Exception ignored) { } } //Load Images: private void pdfLoadImages(final byte[] data) { try { // run async new AsyncTask<Void, Void, String>() { // create and show a progress dialog ProgressDialog progressDialog = ProgressDialog.show(MainActivity.this, "", "Opening..."); @Override protected void onPostExecute(String html) { //after async close progress dialog progressDialog.dismiss(); //load the html in the webview wv.loadDataWithBaseURL("", html, "text/html","UTF-8", ""); } @Override protected String doInBackground(Void... params) { try { //create pdf document object from bytes ByteBuffer bb = ByteBuffer.NEW(data); PDFFile pdf = new PDFFile(bb); //Get the first page from the pdf doc PDFPage PDFpage = pdf.getPage(1, true); //create a scaling value according to the WebView Width final float scale = ViewSize / PDFpage.getWidth() * 0.95f; //convert the page into a bitmap with a scaling value Bitmap page = PDFpage.getImage((int)(PDFpage.getWidth() * scale), (int)(PDFpage.getHeight() * scale), null, true, true); //save the bitmap to a byte array ByteArrayOutputStream stream = new ByteArrayOutputStream(); page.compress(Bitmap.CompressFormat.PNG, 100, stream); byte[] byteArray = stream.toByteArray(); stream.reset(); //convert the byte array to a base64 string String base64 = Base64.encodeToString(byteArray, Base64.NO_WRAP); //create the html + add the first image to the html String html = "<!DOCTYPE html><html><body bgcolor=\"#b4b4b4\"><img src=\"data:image/png;base64,"+base64+"\" hspace=10 vspace=10><br>"; //loop though the rest of the pages and repeat the above for(int i = 2; i <= pdf.getNumPages(); i++) { PDFpage = pdf.getPage(i, true); page = PDFpage.getImage((int)(PDFpage.getWidth() * scale), (int)(PDFpage.getHeight() * scale), null, true, true); page.compress(Bitmap.CompressFormat.PNG, 100, stream); byteArray = stream.toByteArray(); stream.reset(); base64 = Base64.encodeToString(byteArray, Base64.NO_WRAP); html += "<img src=\"data:image/png;base64,"+base64+"\" hspace=10 vspace=10><br>"; } stream.close(); html += "</body></html>"; return html; } catch (Exception e) { Log.d("error", e.toString()); } return null; } }.execute(); System.gc();// run GC } catch (Exception e) { Log.d("error", e.toString()); } } 
Sign up to request clarification or add additional context in comments.

28 Comments

this solution works, but images aren't drawn in the bitmap, even with .sShowImagesset to true, and your version of the library. Do you have any idea why this might happen?
i have downloaded your library, now please tell me, what imports do you use?
why not just use the add missing imports feature that comes with your IDE?
PDFFile pdf = new PDFFile(bb); in the row E/CounterA: java.lang.NullPointerException. How to fix this?
@NicolasTyler I know in above example the images are not stored please tell me where I show the converted bitmap because in Activity this is showing only blank Layout. I have to put PDF files in assets folder or somewhere else? Please suggest.
|
21

I know this question is old but I ran into this problem last week, and none of the answers really worked for me.

Here's how I solve this issue without using third-party libraries.

Based on the code from android developers site using android's PDFRenderer class (API 21+), I wrote the following method:

private ArrayList<Bitmap> pdfToBitmap(File pdfFile) { ArrayList<Bitmap> bitmaps = new ArrayList<>(); try { PdfRenderer renderer = new PdfRenderer(ParcelFileDescriptor.open(pdfFile, ParcelFileDescriptor.MODE_READ_ONLY)); Bitmap bitmap; final int pageCount = renderer.getPageCount(); for (int i = 0; i < pageCount; i++) { PdfRenderer.Page page = renderer.openPage(i); int width = getResources().getDisplayMetrics().densityDpi / 72 * page.getWidth(); int height = getResources().getDisplayMetrics().densityDpi / 72 * page.getHeight(); bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); page.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY); bitmaps.add(bitmap); // close the page page.close(); } // close the renderer renderer.close(); } catch (Exception ex) { ex.printStackTrace(); } return bitmaps; } 

the method returns an array of bitmaps, one bitmap for every page in the pdf file.

The height and width are calculated based on this answer to create better-quality images.

5 Comments

This leads to a OOM exception.
You could try using ARGB_4444, it takes much less memory
Worked like a Charm!!! I wasted a day to implement other solutions and finally, this worked like charm :)
to add background for bitmap add this code stackoverflow.com/a/45297757/8258305
its throwing exception "ava.io.FileNotFoundException: open failed: ENOENT (No such file or directory)" in android version 11
2

This question is a bit old, but I had to do the same today, so this is my solution:

/** * Use this to load a pdf file from your assets and render it to a Bitmap. * * @param context * current context. * @param filePath * of the pdf file in the assets. * @return a bitmap. */ @Nullable public static Bitmap renderToBitmap(Context context, String filePath) { Bitmap bi = null; InputStream inStream = null; try { AssetManager assetManager = context.getAssets(); Log.d(TAG, "Attempting to copy this file: " + filePath); inStream = assetManager.open(filePath); bi = renderToBitmap(context, inStream); } catch (IOException e) { e.printStackTrace(); } finally { try { inStream.close(); } catch (IOException e) { // do nothing because the stream has already been closed } } return bi; } /** * Use this to render a pdf file given as InputStream to a Bitmap. * * @param context * current context. * @param inStream * the inputStream of the pdf file. * @return a bitmap. * @see https://github.com/jblough/Android-Pdf-Viewer-Library/ */ @Nullable public static Bitmap renderToBitmap(Context context, InputStream inStream) { Bitmap bi = null; try { byte[] decode = IOUtils.toByteArray(inStream); ByteBuffer buf = ByteBuffer.wrap(decode); PDFPage mPdfPage = new PDFFile(buf).getPage(0); float width = mPdfPage.getWidth(); float height = mPdfPage.getHeight(); RectF clip = null; bi = mPdfPage.getImage((int) (width), (int) (height), clip, true, true); } catch (IOException e) { e.printStackTrace(); } finally { try { inStream.close(); } catch (IOException e) { // do nothing because the stream has already been closed } } return bi; } 

Also, I am using this library. And my pdf file contains only one page and is an image, may be in other cases, you have to update your code.

I hope this will help someone.

5 Comments

Hi, is there any library like this but instead of clicking the button previous and next the user can scroll between pages of PDF? I'm using the same library.
sorry I have no idea, I just needed to convert pdf images to bitmaps. I would recommend to create a new question about pdf pagination... good luck.
A lot of thanks to you , the code works with the lib github.com/jblough/Android-Pdf-Viewer-Library
@ahmed_khan_89 why output bitmap is smaller then source image in pdf ?
I don't know, I didn't get this issue. But if it might help you, you can choose the width and height of the output bitmap by passing different values in the getImage method.
1

Here is the code, hope it helps. I managed to render all pages into Bitmap.Cheers

 try { pdfViewer = (ImageView) findViewById(R.id.pdfViewer); int x = pdfViewer.getWidth(); int y = pdfViewer.getHeight(); Bitmap bitmap = Bitmap.createBitmap(x, y, Bitmap.Config.ARGB_4444); String StoragePath= Environment.getExternalStorageDirectory()+ "/sample.pdf"; File file = new File(StoragePath); PdfRenderer renderer = new PdfRenderer(ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY)); if (currentPage < 0) { currentPage = 0; } else if (currentPage > renderer.getPageCount()) { } Matrix m = pdfViewer.getImageMatrix(); Rect r = new Rect(0, 0, x, y); renderer.openPage(currentPage).render(bitmap, r, m, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY); pdfViewer.setImageMatrix(m); pdfViewer.setImageBitmap(bitmap); pdfViewer.invalidate(); } catch (Exception ex) { Log.v(TAG, ex.getMessage()); } finally { } 

Comments

0

dependencies

dependencies { implementation 'com.tom_roush:pdfbox-android:1.8.10.1' } 

code

 PDDocument pd = PDDocument.load (new File (in)); PDFRenderer pr = new PDFRenderer (pd); Bitmap bitmap = pr.renderImageWithDPI(0, 300); 

Comments

0

After going through and trying all the answers, none worked for me for all the PDF files. Rendering issues were there in custom font PDF files. Then I tried using library

The code is as follows:

In your app build.gradle file add the following dependency:

implementation 'com.github.barteksc:android-pdf-viewer:3.2.0-beta.1' 

The code for converting PDF pages to images:

 public static List<Bitmap> renderToBitmap(Context context, String filePath) { List<Bitmap> images = new ArrayList<>(); PdfiumCore pdfiumCore = new PdfiumCore(context); try { File f = new File(pdfPath); ParcelFileDescriptor fd = ParcelFileDescriptor.open(f, ParcelFileDescriptor.MODE_READ_ONLY); PdfDocument pdfDocument = pdfiumCore.newDocument(fd); final int pageCount = pdfiumCore.getPageCount(pdfDocument); for (int i = 0; i < pageCount; i++) { pdfiumCore.openPage(pdfDocument, i); int width = pdfiumCore.getPageWidthPoint(pdfDocument, i); int height = pdfiumCore.getPageHeightPoint(pdfDocument, i); Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); pdfiumCore.renderPageBitmap(pdfDocument, bmp, i, 0, 0, width, height); images.add(bmp); } pdfiumCore.closeDocument(pdfDocument); } catch(Exception e) { //todo with exception } return images; } 

So far it is working for me all the PDF files that I tried.

Comments

-1

We can do it using Qoppa PDF toolkit.

Steps to follow to use Qoppa PDF toolkit.

Download it from http://www.qoppa.com/android/pdfsdk/download

This file contains four items:

  1. version_history.txt – This text file will be updated with each new version of the toolkit.
  2. qoppapdf.jar – This is the main jar file for the toolkit. This jar file needs to be added to the classpath for your project.
  3. assets folder – This folder contains assets used by the toolkit, such as fonts and icons. After extracting from the zip files, you will need to copy the files inside this folder to the assets folder in your project.
  4. libs folder – This folder contains native Android libraries, these libraries are needed to decode certain JPEG images as well as JPEG 2000 images that are not supported by Android. The contents of the libs folder need to be copied to the libs folder in your project. If you don’t have a libs folder in your project, create one and copy the contents of this folder into it.

Code is:

 //Converting PDF to Bitmap Image... StandardFontTF.mAssetMgr = getAssets(); //Load document to get the first page try { PDFDocument pdf = new PDFDocument("/sdcard/PDFFilename.pdf", null); PDFPage page = pdf.getPage(0); //creating Bitmap and canvas to draw the page into int width = (int)Math.ceil(page.getDisplayWidth()); int height = (int)Math.ceil(page.getDisplayHeight()); Bitmap bm = Bitmap.createBitmap(width, height, Config.ARGB_8888); Canvas c = new Canvas(bm); page.paintPage(c); //Saving the Bitmap OutputStream os = new FileOutputStream("/sdcard/GeneratedImageByQoppa.jpg"); bm.compress(CompressFormat.JPEG, 80, os); os.close(); } catch (PDFException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } 

7 Comments

this kinda works but its not 100% and it puts a watermark on the pages.
Don't try this, waste of time, who wants their user to read pdfs with watermarks?
Then please provide the solution that prevents the watermark without having licence.
Its simple, you either pay for it or you use an alternative library.
qPDF - Don't bother to get the full version unless you're willing to pay $6000 for the first year and $3000/year afterwards.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.