blob: 1716d426b362ee902d5815dd1b5b26ff82c8b04a [file] [log] [blame]
Julian Mancinid522fe62017-07-11 12:51:35 -07001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.internal.content;
18
19import android.annotation.Nullable;
20import android.content.res.AssetFileDescriptor;
21import android.graphics.Bitmap;
22import android.graphics.Point;
23import android.graphics.Rect;
24import android.graphics.pdf.PdfRenderer;
25import android.os.AsyncTask;
26import android.os.ParcelFileDescriptor;
27
28import libcore.io.IoUtils;
29import libcore.io.Streams;
30
31import java.io.ByteArrayInputStream;
32import java.io.ByteArrayOutputStream;
33import java.io.File;
34import java.io.FileOutputStream;
35import java.io.IOException;
36
37/**
38 * Utils class for extracting PDF Thumbnails
39 */
40public final class PdfUtils {
41
42 private PdfUtils() {
43 }
44
45 /**
46 * Returns the front page of the pdf as a thumbnail
47 * @param file Given PDF File
48 * @param size Cropping of the front page.
49 * @return AssetFileDescriptor containing the thumbnail as a bitmap.
50 * @throws IOException if the file isn't a pdf or if the file doesn't exist.
51 */
52 public static @Nullable AssetFileDescriptor openPdfThumbnail(File file, Point size)
53 throws IOException {
54 // Create the bitmap of the PDF's first page
55 ParcelFileDescriptor pdfDescriptor =
56 ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
57 PdfRenderer renderer = new PdfRenderer(pdfDescriptor);
58 PdfRenderer.Page frontPage = renderer.openPage(0);
59 Bitmap thumbnail = Bitmap.createBitmap(size.x, size.y,
60 Bitmap.Config.ARGB_8888);
61 frontPage.render(thumbnail, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
62
63 // Create an AssetFileDescriptor that contains the Bitmap's information
64 final ByteArrayOutputStream out = new ByteArrayOutputStream();
65 // Quality is an integer that determines how much compression is used.
66 // However, this integer is ignored when using the PNG format
67 int quality = 100;
68 // The use of Bitmap.CompressFormat.JPEG leads to a black PDF background on the thumbnail
69 thumbnail.compress(Bitmap.CompressFormat.PNG, quality, out);
70
71 final ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
72
73 final ParcelFileDescriptor[] fds = ParcelFileDescriptor.createReliablePipe();
74 new AsyncTask<Object, Object, Object>() {
75 @Override
76 protected Object doInBackground(Object... params) {
77 final FileOutputStream fos = new FileOutputStream(fds[1].getFileDescriptor());
78 try {
79 Streams.copy(in, fos);
80 } catch (IOException e) {
81 throw new RuntimeException(e);
82 }
83 IoUtils.closeQuietly(fds[1]);
84 try {
85 pdfDescriptor.close();
86 } catch (IOException e) {
87 throw new RuntimeException(e);
88 }
89 return null;
90 }
91 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
92 pdfDescriptor.close();
93 return new AssetFileDescriptor(fds[0], 0, AssetFileDescriptor.UNKNOWN_LENGTH);
94 }
95
96}