2012-01-11 11 views
37

Ho bisogno di convertire PDFfile (pagina PDF) in un Bitmap (o file immagine) in Android.Convertire una pagina Pdf in Bitmap in Android Java

1. Vaso Pdfbox da utilizzare da Apache. Ma usa alcune classi Java che non sono supportate in Android. 2. Provato jar Itext che converte l'immagine in pdf (ho bisogno della sua operazione inversa) Come che ho provato molti vasi. Ma nessun risultato positivo.

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

Sto ottenendo il file immagine, enter image description here

Invece di, 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, un altro modo per visualizzare file pdf in Android utilizzando la funzione integrato all'interno dell'applicazione?

+0

Possiamo convertire il pdf in immagine usando gli strumenti awt in java.but awt non è supportato da android.i sto usando anche itext..se so python puoi convertire pdf in bitmap usando ghostscript. –

+0

Non conosco python .. C'è un modo per farlo in java? – Neela

+0

Si prega di consultare il codice sopra .. Ho usato il barattolo dal link, https://github.com/jblough/Android-Pdf-Viewer-Library/blob/master/PdfViewer.jar Ho potuto convertire la pagina PDF in jpg file. Ma l'immagine convertita è parzialmente convertita. Non so dove mi sbaglio? – Neela

risposta

0

Possiamo farlo utilizzando Qoppa PDF toolkit.

Passi da seguire per utilizzare Qoppa PDF toolkit.

scaricarlo da http://www.qoppa.com/android/pdfsdk/download

Questo file contiene quattro voci:

  1. version_history.txt - Questo file di testo verrà aggiornato ad ogni nuova versione del toolkit.
  2. qoppapdf.jar - Questo è il file jar principale per il toolkit. Questo file jar deve essere aggiunto al classpath per il tuo progetto.
  3. cartella delle risorse: questa cartella contiene le risorse utilizzate dal toolkit, ad esempio i caratteri e le icone. Dopo l'estrazione dai file zip, sarà necessario copiare i file all'interno di questa cartella nella cartella delle risorse del progetto.
  4. cartella libs - Questa cartella contiene librerie native native, queste librerie sono necessarie per decodificare determinate immagini JPEG e immagini JPEG 2000 che non sono supportate da Android. Il contenuto della cartella libs deve essere copiato nella cartella libs nel progetto. Se non si dispone di una cartella libs nel progetto, crearne una e copiarne il contenuto di questa cartella.

Codice è:

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

questo tipo funziona ma non è al 100% e mette una filigrana sulle pagine. –

+0

al fine di non ottenere ottenere le filigrane è necessario acquistare la versione a pagamento. – Jagadeesh

+0

L'ho già fatto con una libreria gratuita. –

28

ho risolto questo problema. è semplice come lasciare che il dispositivo abbia il tempo di rendere ogni pagina.

Per risolvere questo tutto ciò che dovete fare è cambiare

PDFPage page = pdf_file.getPage(2); 

a

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

In primo luogo per visualizzare un PDF in Android è necessario convertire il file PDF in immagini per poi visualizzare all'utente . (Vado a usare una webview)

Quindi per fare questo abbiamo bisogno di questo library. È la mia versione modificata di questo git.

Dopo aver importato la libreria nel progetto, è necessario creare la propria attività.

L'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> 

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

questa soluzione funziona, ma le immagini non vengono disegnate nella bitmap, anche con '.sShowImages'set su' true' e la tua versione della libreria. Hai idea del perché questo potrebbe accadere? – Agos

+0

ho scaricato la tua libreria, ora per favore dimmi, quali sono le importazioni che usi? –

+0

perché non utilizzare semplicemente la funzionalità di importazione mancante mancante fornita con l'IDE? –

2

questa domanda è un po 'vecchio, ma ho dovuto fare lo stesso oggi, quindi questa è la mia soluzione:

/** 
* 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; 
} 

Inoltre, sto usando questo library. E il mio file pdf contiene solo una pagina ed è un'immagine, potrebbe essere in altri casi, devi aggiornare il tuo codice.

Spero che questo aiuti qualcuno.

+0

Ciao, c'è qualche libreria come questa ma invece di fare clic sul pulsante precedente e successivo l'utente può scorrere tra le pagine del PDF? Sto usando la stessa libreria. –

+0

scusate non ne ho idea, ho solo bisogno di convertire le immagini pdf in bitmap. Consiglierei di creare una nuova domanda sull'impaginazione in pdf ... buona fortuna. –

+1

Un sacco di ringraziamenti a te, il codice funziona con la lib https://github.com/jblough/Android-Pdf-Viewer-Library/ – NickUnuchek

0

Ecco il codice, spero che aiuti. Sono riuscito a rendere tutte le pagine in 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 { 

    } 
+0

il tuo codice non supporta le versioni sotto api 19 – Vicky

2

So che questa domanda è vecchio ma mi sono imbattuto in questo problema la scorsa settimana, e nessuna delle risposte davvero lavorato per me.

Ecco come risolvo questo problema senza utilizzare librerie di terze parti.

In base al codice da parte degli sviluppatori di Android site utilizzando classe PDFRenderer di Android (API 21+), ho scritto il seguente metodo:

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; 

} 

il metodo restituisce un array di immagini bitmap, una bitmap per ogni pagina del file PDF.

L'altezza e la larghezza sono calcolate in base a this answer per creare immagini di qualità migliore.