在Android Java中将PDF页面转换为位图
我需要将PDF文件(PDF页面)转换为Android中的位图(或图像文件)。
1.使用Apache的Pdfbox jar。 但是它使用了一些在android中不支持的java类。 2.试图将图像转换成pdf的Itext jar(我需要它的反向操作)就像我已经尝试了很多的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);
我正在获取图像文件,
代替,
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(); } } }
否则,任何其他方式来显示PDF文件在android中使用函数内置的应用程序?
我解决了这个问题。 就像让设备有时间渲染每个页面一样简单。
要解决这个问题,你需要做的就是改变
PDFPage page = pdf_file.getPage(2);
至
PDFPage page = pdf_file.getPage(2, true);
首先要在Android中查看PDF,您必须将PDF转换为图像,然后将其显示给用户。 (我打算使用webview)
所以要做到这一点,我们需要这个库 。 这是我编辑的这个混帐版本。
将库导入到项目后,您需要创build活动。
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()); } }
这个问题有点老了,但今天我必须这样做,所以这是我的解决scheme:
/** * 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; }
另外,我正在使用这个库 。 而我的PDF文件只包含一个页面,是一个图像,可能在其他情况下,你必须更新你的代码。
我希望这会帮助别人。
我知道这个问题很老,但是我上周遇到了这个问题,没有一个答案真的对我有用。
以下是我如何解决这个问题,而不使用第三方库。
基于使用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; }
该方法返回一个位图数组,pdf文件中每个页面的一个位图。
根据此答案计算高度和宽度,以创build更高质量的图像。
我们可以使用Qoppa PDF工具包来完成。
遵循使用Qoppa PDF工具包的步骤。
从http://www.qoppa.com/android/pdfsdk/download下载;
这个文件包含四个项目:
- version_history.txt – 该文本文件将随每个新版本的工具包一起更新。
- qoppapdf.jar – 这是工具包的主要jar文件。 这个jar文件需要被添加到你的项目的类path中。
- 资产文件夹 – 此文件夹包含工具包使用的资产,例如字体和图标。 从zip文件中提取后,您需要将此文件夹中的文件复制到项目中的assets文件夹中。
- libs文件夹 – 此文件夹包含原生Android库,这些库需要解码某些JPEG图像以及Android不支持的JPEG 2000图像。 libs文件夹的内容需要复制到项目中的libs文件夹中。 如果您的项目中没有libs文件夹,请创build一个并将此文件夹的内容复制到其中。
代码是:
//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(); }
这是代码,希望它有帮助。 我设法将所有页面渲染到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 { }