为了账号安全,请及时绑定邮箱和手机立即绑定

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

/ 猿问

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

富国沪深 2019-08-13 09:46:04

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

我需要将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);

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


查看完整描述

4 回答

?
zhangjinhuang

有实现了的么?我今天也遇到了这问题,需要将pdf文件解析成bitmap

查看完整回答
反对 回复 2019-11-08
?
繁花如伊

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

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

PDFPage page = pdf_file.getPage(2);

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

首先,要在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>

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


查看完整回答
反对 回复 2019-08-13
?
眼眸繁星

我知道这个问题已经过时但我上周遇到了这个问题,但没有一个答案对我有用。

以下是我在不使用第三方库的情况下解决此问题的方法。

基于android开发者网站使用android的PDFRenderer类(API 21+)的代码,我编写了以下方法:

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

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


查看完整回答
反对 回复 2019-08-13
?
互换的青春

这个问题有点旧,但今天我必须这样做,所以这是我的解决方案:

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

另外,我正在使用这个。我的pdf文件只包含一个页面,是一个图像,在其他情况下,您必须更新代码。

我希望这会对某人有所帮助。


查看完整回答
反对 回复 2019-08-13

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信