2012-05-22 460 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; 
    }