Convert a Pdf page into Bitmap in Android Java Convert a Pdf page into Bitmap in Android Java android android

Convert a Pdf page into Bitmap in Android Java


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:@Overrideprotected 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());    }}


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.


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. */@Nullablepublic 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/ */@Nullablepublic 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.