我需要做的就是拍攝(本地保存的)PDF-document
和將其中的一個或全部頁面轉換爲像JPG或PNG格式的格式。如何將PDF頁面轉換爲Android中的圖像?
我試過PDF渲染的大量的/像APV PDF Viewer,APDFViewer,droidreader,android-pdf,MuPdf和查看解決方案很多人,但無法弄清楚迄今爲止該如何將PDF頁面轉換爲圖像?。
編輯:另外,我寧願有一個PDF到圖像轉換器,而不是PDF格式的渲染器,我需要編輯將PDF轉換爲圖像。
我需要做的就是拍攝(本地保存的)PDF-document
和將其中的一個或全部頁面轉換爲像JPG或PNG格式的格式。如何將PDF頁面轉換爲Android中的圖像?
我試過PDF渲染的大量的/像APV PDF Viewer,APDFViewer,droidreader,android-pdf,MuPdf和查看解決方案很多人,但無法弄清楚迄今爲止該如何將PDF頁面轉換爲圖像?。
編輯:另外,我寧願有一個PDF到圖像轉換器,而不是PDF格式的渲染器,我需要編輯將PDF轉換爲圖像。
您需要針對相同的需求來看這個項目的開源項目,這對您也可以做更多的事情。
項目:PdfRenderer
有一個在pdfview
包命名爲PDFPage.java一個Java類。該類有一個獲取頁面圖像的方法。
我也在我的測試項目中執行了同樣的事情,並且java代碼是here for you。我創建了一個方法showPage
,它接受頁面號和縮放級別並將該頁作爲Bitmap
返回。
希望這可以幫助你。您只需要爲此獲取該項目或JAR,請閱讀記錄良好的JAVADOC,然後嘗試和實施與之相同的步驟。
把你的時間,編碼快樂:)
感謝您的回覆,我會馬上查看。 – Pieter888
我正在嘗試使用您製作的showPage方法。但是我在發佈的pastebin 93行上遇到了問題。顯然'PDFPage'試圖從'java.awt.geom'中使用一些Android不支持的類('Rectangle2D','ImageObserver','Image')。你是怎麼做到的? – Pieter888
是的,我將'pdf-renderer-1.0.5.jar'添加到構建路徑。這是我爲'Rectangle2D'得到的錯誤:'無法解析java.awt.geom.Rectangle2D類型。它是從所需的.class文件間接引用的,而且我在我之前的評論中提到的類中出現同樣的錯誤 – Pieter888
爲了支持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時間(我已經在註釋中標記了它們)。
我會說你一個簡單的技巧不是一個完整的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());
}
這就是我的全部,希望你能幫到你。
最後我發現這個很簡單的解決方案, 從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卡查看轉換後的圖片。如果您需要任何幫助,請告訴我。
用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;
}
http://stackoverflow.com/questions/6757434/how-to-convert-pdf-into-image –
@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
嗯,我沒有測試,但如果任何人確認,那麼我會刪除這個答案。 –