Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
254 views
in Technique[技术] by (71.8m points)

Convert a Pdf page into Bitmap in Android Java

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?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...