2012-05-22 308 views
19

我需要做的就是拍攝(本地保存的)PDF-document將其中的一個或全部頁面轉換爲像JPG或PNG格式的格式。如何將PDF頁面轉換爲Android中的圖像?

我試過PDF渲染的大量的/像​​APV PDF ViewerAPDFViewerdroidreaderandroid-pdfMuPdf和查看解決方案很多人,但無法弄清楚迄今爲止該如何將PDF頁面轉換爲圖像?

編輯:另外,我寧願有一個PDF到圖像轉換器,而不是PDF格式的渲染器,我需要編輯將PDF轉換爲圖像。

+0

http://stackoverflow.com/questions/6757434/how-to-convert-pdf-into-image –

+1

@AgarwalShankar,不知道你是否已經測試此代碼自己。 **這不會奏效**爲什麼? **,因爲此代碼中使用的核心類PDFImageWriter對java.awt。*類有依賴性,**請查看[源代碼](http://grepcode.com/file/repo1.maven.org/maven2/org .apache.pdfbox/pdfbox/1.6.0/org/apache/pdfbox/util/PDFImageWriter.java)。我希望你或投票的人可以告訴我我錯了,從我的基本知識:** Java awt不支持Android。** – yorkw

+0

嗯,我沒有測試,但如果任何人確認,那麼我會刪除這個答案。 –

回答

8

您需要針對相同的需求來看這個項目的開源項目,這對您也可以做更多的事情。

項目:PdfRenderer

有一個在pdfview包命名爲PDFPage.java一個Java類。該類有一個獲取頁面圖像的方法。

我也在我的測試項目中執行了同樣的事情,並且java代碼是here for you。我創建了一個方法showPage,它接受頁面號和縮放級別並將該頁作爲Bitmap返回。

希望這可以幫助你。您只需要爲此獲取該項目或JAR,請閱讀記錄良好的JAVADOC,然後嘗試和實施與之相同的步驟。

把你的時間,編碼快樂:)

+0

感謝您的回覆,我會馬上查看。 – Pieter888

+2

我正在嘗試使用您製作的showPage方法。但是我在發佈的pastebin 93行上遇到了問題。顯然'PDFPage'試圖從'java.awt.geom'中使用一些Android不支持的類('Rectangle2D','ImageObserver','Image')。你是怎麼做到的? – Pieter888

+0

是的,我將'pdf-renderer-1.0.5.jar'添加到構建路徑。這是我爲'Rectangle2D'得到的錯誤:'無法解析java.awt.geom.Rectangle2D類型。它是從所需的.class文件間接引用的,而且我在我之前的評論中提到的類中出現同樣的錯誤 – Pieter888

6

來自Android的API起21 PdfRenderer是你在找什麼。

+1

如何支持低至14的API版本? –

8

爲了支持API 8及以上的,遵循:

使用這個庫:android-pdfview和下面的代碼,就可以可靠地轉換的PDF頁面轉換成圖片(JPG,PNG):

DecodeServiceBase decodeService = new DecodeServiceBase(new PdfContext()); 
decodeService.setContentResolver(mContext.getContentResolver()); 

// a bit long running 
decodeService.open(Uri.fromFile(pdf)); 

int pageCount = decodeService.getPageCount(); 
for (int i = 0; i < pageCount; i++) { 
    PdfPage page = decodeService.getPage(i); 
    RectF rectF = new RectF(0, 0, 1, 1); 

    // do a fit center to 1920x1080 
    double scaleBy = Math.min(AndroidUtils.PHOTO_WIDTH_PIXELS/(double) page.getWidth(), // 
      AndroidUtils.PHOTO_HEIGHT_PIXELS/(double) page.getHeight()); 
    int with = (int) (page.getWidth() * scaleBy); 
    int height = (int) (page.getHeight() * scaleBy); 

    // you can change these values as you to zoom in/out 
    // and even distort (scale without maintaining the aspect ratio) 
    // the resulting images 

    // Long running 
    Bitmap bitmap = page.renderBitmap(with, height, rectF); 

    try { 
     File outputFile = new File(mOutputDir, System.currentTimeMillis() + FileUtils.DOT_JPEG); 
     FileOutputStream outputStream = new FileOutputStream(outputFile); 

     // a bit long running 
     bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream); 

     outputStream.close(); 
    } catch (IOException e) { 
     LogWrapper.fatalError(e); 
    } 
} 

你應該在後臺做這項工作,即使用AsyncTask或類似的東西,因爲不少方法需要計算或IO時間(我已經在註釋中標記了它們)。

+0

這是非常有益的,並以非常有效的方式工作。 – AnkitRox

+0

雅它真的非常快,並按預期工作。只需要17秒左右即可將PDF格式的12頁PDF圖像轉換爲PDF格式的圖像。感謝那個偉大的職位。 – Smeet

+0

該項目不再維護。 –

1

我會說你一個簡單的技巧不是一個完整的solution.Once如果你成功地渲染PDF頁面,你會得到它的位圖從屏幕遵循

View view = MuPDFActivity.this.getWindow().getDecorView(); 
if (false == view.isDrawingCacheEnabled()) { 
    view.setDrawingCacheEnabled(true); 
} 
Bitmap bitmap = view.getDrawingCache(); 

然後你就可以保存此位,那是你的pdf頁在本地圖像

try { 
    new File(Environment.getExternalStorageDirectory()+"/PDF Reader").mkdirs(); 
    File outputFile = new File(Environment.getExternalStorageDirectory()+"/PDF Reader", System.currentTimeMillis()+"_pdf.jpg"); 
    FileOutputStream outputStream = new FileOutputStream(outputFile); 

    // a bit long running 
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream); 
     outputStream.close(); 
} catch (IOException e) { 
    Log.e("During IMAGE formation", e.toString()); 
} 

這就是我的全部,希望你能幫到你。

1

最後我發現這個很簡單的解決方案, 從here下載庫。下面的代碼

使用從PDF獲得的圖像:

import android.app.ProgressDialog; 
import android.content.Context; 
import android.content.Intent; 
import android.graphics.Bitmap; 
import android.graphics.RectF; 
import android.net.Uri; 
import android.os.AsyncTask; 
import android.os.Environment; 
import android.provider.MediaStore; 

import org.vudroid.core.DecodeServiceBase; 
import org.vudroid.core.codec.CodecPage; 
import org.vudroid.pdfdroid.codec.PdfContext; 

import java.io.ByteArrayOutputStream; 
import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.OutputStream; 
import java.util.ArrayList; 

/** 
* Created by deepakd on 06-06-2016. 
*/ 
public class PrintUtils extends AsyncTask<Void, Void, ArrayList<Uri>> 
{ 
    File file; 
    Context context; 
    ProgressDialog progressDialog; 

    public PrintUtils(File file, Context context) 
    { 

     this.file = file; 
     this.context = context; 
    } 

    @Override 
    protected void onPreExecute() 
    { 
     super.onPreExecute(); 
     // create and show a progress dialog 
     progressDialog = ProgressDialog.show(context, "", "Please wait..."); 
     progressDialog.show(); 
    } 

    @Override 
    protected ArrayList<Uri> doInBackground(Void... params) 
    { 
     ArrayList<Uri> uris = new ArrayList<>(); 

     DecodeServiceBase decodeService = new DecodeServiceBase(new PdfContext()); 
     decodeService.setContentResolver(context.getContentResolver()); 
     // a bit long running 
     decodeService.open(Uri.fromFile(file)); 
     int pageCount = decodeService.getPageCount(); 
     for (int i = 0; i < pageCount; i++) 
     { 
      CodecPage page = decodeService.getPage(i); 
      RectF rectF = new RectF(0, 0, 1, 1); 
      // do a fit center to A4 Size image 2480x3508 
      double scaleBy = Math.min(UIUtils.PHOTO_WIDTH_PIXELS/(double) page.getWidth(), // 
        UIUtils.PHOTO_HEIGHT_PIXELS/(double) page.getHeight()); 
      int with = (int) (page.getWidth() * scaleBy); 
      int height = (int) (page.getHeight() * scaleBy); 
      // Long running 
      Bitmap bitmap = page.renderBitmap(with, height, rectF); 
      try 
      { 
       OutputStream outputStream = FileUtils.getReportOutputStream(System.currentTimeMillis() + ".JPEG"); 
       // a bit long running 
       bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream); 
       outputStream.close(); 
       // uris.add(getImageUri(context, bitmap)); 
       uris.add(saveImageAndGetURI(bitmap)); 
      } 
      catch (IOException e) 
      { 
       e.printStackTrace(); 
      } 
     } 
     return uris; 
    } 

    @Override 
    protected void onPostExecute(ArrayList<Uri> uris) 
    { 
     progressDialog.hide(); 
     //get all images by uri 
     //ur implementation goes here 
    } 




    public void shareMultipleFilesToBluetooth(Context context, ArrayList<Uri> uris) 
    { 
     try 
     { 
      Intent sharingIntent = new Intent(); 
      sharingIntent.setAction(Intent.ACTION_SEND_MULTIPLE); 
      sharingIntent.setType("image/*"); 
      // sharingIntent.setPackage("com.android.bluetooth"); 
      sharingIntent.putExtra(Intent.EXTRA_STREAM, uris); 
      context.startActivity(Intent.createChooser(sharingIntent,"Print PDF using...")); 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
     } 
    } 





    private Uri saveImageAndGetURI(Bitmap finalBitmap) { 
     String root = Environment.getExternalStorageDirectory().toString(); 
     File myDir = new File(root + "/print_images"); 
     myDir.mkdirs(); 
     String fname = "Image-"+ MathUtils.getRandomID() +".jpeg"; 
     File file = new File (myDir, fname); 
     if (file.exists()) file.delete(); 
     try { 
      FileOutputStream out = new FileOutputStream(file); 
      finalBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out); 
      out.flush(); 
      out.close(); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     return Uri.parse("file://"+file.getPath()); 
    } 

} 

FileUtils.java

package com.airdata.util; 

import android.net.Uri; 
import android.os.Environment; 
import android.support.annotation.NonNull; 

import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.OutputStream; 

/** 
* Created by DeepakD on 21-06-2016. 
*/ 
public class FileUtils 
{ 

    @NonNull 
    public static OutputStream getReportOutputStream(String fileName) throws FileNotFoundException 
{ 
    // create file 
    File pdfFolder = getReportFilePath(fileName); 
    // create output stream 
    return new FileOutputStream(pdfFolder); 
} 

    public static Uri getReportUri(String fileName) 
    { 
     File pdfFolder = getReportFilePath(fileName); 
     return Uri.fromFile(pdfFolder); 
    } 
    public static File getReportFilePath(String fileName) 
    { 
     /*File file = new File(Environment.getExternalStoragePublicDirectory(
       Environment.DIRECTORY_DOWNLOADS), FileName);*/ 
     File file = new File(Environment.getExternalStorageDirectory() + "/AirPlanner/Reports"); 
     //Create report directory if does not exists 
     if (!file.exists()) 
     { 
      //noinspection ResultOfMethodCallIgnored 
      file.mkdirs(); 
     } 
     file = new File(Environment.getExternalStorageDirectory() + "/AirPlanner/Reports/" + fileName); 
     return file; 
    } 
} 

可以在畫廊或SD卡查看轉換後的圖片。如果您需要任何幫助,請告訴我。

+0

其工作正常但打開密碼保護的PDF格式的異常請幫助@ dd619 –

+0

對不起bhai ...不能幫助你在密碼保護pdf。 – dd619

+0

好吧,我收到了pdfview庫不支持它 –

0

用lib https://github.com/barteksc/PdfiumAndroid

public Bitmap getBitmap(File file){ 
int pageNum = 0; 
      PdfiumCore pdfiumCore = new PdfiumCore(context); 
      try { 
       PdfDocument pdfDocument = pdfiumCore.newDocument(openFile(file)); 
       pdfiumCore.openPage(pdfDocument, pageNum); 

       int width = pdfiumCore.getPageWidthPoint(pdfDocument, pageNum); 
       int height = pdfiumCore.getPageHeightPoint(pdfDocument, pageNum); 


       // ARGB_8888 - best quality, high memory usage, higher possibility of OutOfMemoryError 
       // RGB_565 - little worse quality, twice less memory usage 
       Bitmap bitmap = Bitmap.createBitmap(width , height , 
         Bitmap.Config.RGB_565); 
       pdfiumCore.renderPageBitmap(pdfDocument, bitmap, pageNum, 0, 0, 
         width, height); 
       //if you need to render annotations and form fields, you can use 
       //the same method above adding 'true' as last param 

       pdfiumCore.closeDocument(pdfDocument); // important! 
       return bitmap; 
      } catch (IOException ex) { 
       ex.printStackTrace(); 
      } 
      return null; 
} 

public static ParcelFileDescriptor openFile(File file) { 
     ParcelFileDescriptor descriptor; 
     try { 
      descriptor = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY); 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
      return null; 
     } 
     return descriptor; 
    }