将Pdf页面转换为Android Java中的Bitmap

Nee*_*ela 38 pdf android

我需要将PDF文件(PDF页面)转换为Android中的位图(或图像文件).

1.使用Apache的Pdfbox jar.但是它使用了android中不支持的一些java类.2.尝试将图像转换为pdf的Itext jar(我需要它的反向操作)就像我尝试了很多罐子一样.但没有积极的结果.

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);
Run Code Online (Sandbox Code Playgroud)

我正在获取图像文件, 在此输入图像描述

代替, 在此输入图像描述

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

否则,使用内置在应用程序中的函数在android中显示pdf文件的任何其他方式?

Nic*_*ler 28

我解决了这个问题.它就像让设备有时间渲染每个页面一样简单.

要解决这个问题,你所要做的就是改变

PDFPage page = pdf_file.getPage(2);
Run Code Online (Sandbox Code Playgroud)

PDFPage page = pdf_file.getPage(2, true);
Run Code Online (Sandbox Code Playgroud)

首先,要在Android中查看PDF,您必须将PDF转换为图像,然后将其显示给用户.(我将使用webview)

所以要做到这一点,我们需要这个.这是我编辑的这个git的版本.

将库导入项目后,需要创建活动.

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>
Run Code Online (Sandbox Code Playgroud)

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());
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

我知道这个问题很老,但是上周我遇到了这个问题,但没有一个答案真正适合我。

这是不使用第三方库即可解决此问题的方法。

根据使用android的PDFRenderer类(API 21+)的android开发人员站点的代码,我编写了以下方法:

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;

}
Run Code Online (Sandbox Code Playgroud)

该方法返回一个位图数组,pdf文件中的每个页面一个位图。

根据此答案计算高度和宽度,以创建质量更好的图像。

  • 这会导致 OOM 异常。 (2认同)
  • 工作起来就像一个魅力!我浪费了一天的时间来实施其他解决方案,最后,这很有魅力:) (2认同)

Jag*_*esh -1

我们可以使用 Qoppa PDF 工具包来完成。

\n\n

使用 Qoppa PDF 工具包的步骤。

\n\n

从http://www.qoppa.com/android/pdfsdk/download下载

\n\n

该文件包含四项:

\n\n
    \n
  1. version_history.txt \xe2\x80\x93 此文本文件将随工具包的每个新版本进行更新。
  2. \n
  3. qoppapdf.jar \xe2\x80\x93 这是该工具包的主 jar 文件。需要将此 jar 文件添加到项目的类路径中。
  4. \n
  5. 资产文件夹 \xe2\x80\x93 此文件夹包含工具包使用的资产,例如字体和图标。从 zip 文件中解压后,您需要将此文件夹中的文件复制到项目中的 asset 文件夹中。
  6. \n
  7. libs 文件夹 \xe2\x80\x93 该文件夹包含本机 Android 库,需要这些库来解码某些 JPEG 图像以及 Android 不支持的 JPEG 2000 图像。需要将libs文件夹的内容复制到项目中的libs文件夹中。如果您的项目中没有\xe2\x80\x99 文件夹,请创建一个文件夹并将该文件夹的内容复制到其中。
  8. \n
\n\n

代码是:

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

  • 不要尝试这个,浪费时间,谁希望他们的用户阅读带有水印的pdf? (2认同)
  • 那么请提供在没有许可证的情况下防止水印的解决方案。 (2认同)
  • 很简单,您要么付费,要么使用替代库。 (2认同)
  • qPDF - 除非您愿意第一年支付 6000 美元,之后每年支付 3000 美元,否则不必费心去获取完整版本。 (2认同)