背景:
公司项目要求用户可以在手机端查看发票并将发票已图片的形式保存到相册,以便打印,问题来了,因为发票是.pdf,android不支持直接查看pdf,所以要下载下来然后在手机上看,当时的需求是要下载下来在App上查看,经查找,使用了第三方的插件==》PDFView, PDFView基于Google的VuDroid类库来解码PDF文件,在APP内直接加载PDF文件,效果也不错;到这是一路的小平坡,坑来了,如何把pdf文件以图片的形式存到相册,在网上也找了一些资料,以下是解决办法:
解决思路:
利用PdfRenderer这个类降pdf文件转成bitmap集合,然后将bitmap集合转成图片集合依次存入到相册。
代码实现
- pdf文件转成bitmap集合
private ArrayList<Bitmap> pdfToBitmap(File pdfFile) {
ArrayList<Bitmap> bitmaps = new ArrayList<>();
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
PdfRenderer renderer = new PdfRenderer(ParcelFileDescriptor.open(pdfFile, ParcelFileDescriptor.MODE_READ_ONLY));
Bitmap bitmap;
final int pageCount = renderer.getPageCount();
Log.e("test_sign", "图片de 张数: " +pageCount);
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);
//todo 以下三行处理图片存储到本地出现黑屏的问题,这个涉及到背景问题
Canvas canvas = new Canvas(bitmap);
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(bitmap, 0, 0, null);
Rect r = new Rect(0, 0, width, height);
page.render(bitmap, r, 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;
}
得到bitmap集合之后,将bitmap转成图片存到相册。
private void saveImageToGallery(Context context, ArrayList<Bitmap> bitmaps) {
// 首先保存图片
File appDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "dearxy";);
for (int i = 0; i < bitmaps.size(); i++) {
if (!appDir.exists()) {
appDir.mkdir();
}
String fileName = System.currentTimeMillis() + ".jpg";
File file = new File(appDir, fileName);
Log.e("test_sign", "图片全路径localFile = " + appDir.getAbsolutePath() + fileName);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
bitmaps.get(i).compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
showToast("保存到相册失败!");
e.printStackTrace();
} catch (IOException e) {
showToast("保存到相册失败!");
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
//回收
bitmaps.get(i).recycle();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 其次把文件插入到系统图库
try {
MediaStore.Images.Media.insertImage(context.getContentResolver(),
file.getAbsolutePath(), fileName, null);
} catch (FileNotFoundException e) {
showToast("保存到相册失败!");
e.printStackTrace();
}
}
showToast("已保存到手机相册!");
// 最后通知图库更新
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
Uri.fromFile(new File(appDir.getPath()))));
}
这样就能在相册图库里看到存进去的图片啦。
注意:
这期间就有一个问题,就是添加到相册的图片显示不出来,显示黑色,不过我贴出来的代码里面已经处理了,就是TODO那里
出现黑色原理分析:有个原理在里面,bitmap转jpg的时候,他本身有个空白背景是黑色的,然后当你用imageview去显示的时候,imageview会直接把图片背景变成白色,所以你能看得到,但是当你直接存储到本地的时候,那么背景为黑色的时候就会显现出来,所以看到的是黑色,所以我这个时候通过画布canvas把背景强制为白色,图片就有了
Canvas canvas = new Canvas(bitmap);
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(bitmap, 0, 0, null);
到此结束。