show pdf previews in media browser

fixes #3639
This commit is contained in:
Daniel Gultsch 2020-02-14 16:02:12 +01:00
parent c34d40ebff
commit d64bc1776b
2 changed files with 49 additions and 11 deletions

View file

@ -424,18 +424,22 @@ public class FileBackend {
} }
public Bitmap getPreviewForUri(Attachment attachment, int size, boolean cacheOnly) { public Bitmap getPreviewForUri(Attachment attachment, int size, boolean cacheOnly) {
final String key = "attachment_" + attachment.getUuid().toString() + "_" + String.valueOf(size); final String key = "attachment_" + attachment.getUuid().toString() + "_" + size;
final LruCache<String, Bitmap> cache = mXmppConnectionService.getBitmapCache(); final LruCache<String, Bitmap> cache = mXmppConnectionService.getBitmapCache();
Bitmap bitmap = cache.get(key); Bitmap bitmap = cache.get(key);
if (bitmap != null || cacheOnly) { if (bitmap != null || cacheOnly) {
return bitmap; return bitmap;
} }
if (attachment.getMime() != null && attachment.getMime().startsWith("video/")) { final String mime = attachment.getMime();
if ("application/pdf".equals(mime) && Compatibility.runsTwentyOne()) {
bitmap = cropCenterSquarePdf(attachment.getUri(), size);
drawOverlay(bitmap, paintOverlayBlackPdf(bitmap) ? R.drawable.open_pdf_black : R.drawable.open_pdf_white, 0.75f);
} else if (mime != null && mime.startsWith("video/")) {
bitmap = cropCenterSquareVideo(attachment.getUri(), size); bitmap = cropCenterSquareVideo(attachment.getUri(), size);
drawOverlay(bitmap, paintOverlayBlack(bitmap) ? R.drawable.play_video_black : R.drawable.play_video_white, 0.75f); drawOverlay(bitmap, paintOverlayBlack(bitmap) ? R.drawable.play_video_black : R.drawable.play_video_white, 0.75f);
} else { } else {
bitmap = cropCenterSquare(attachment.getUri(), size); bitmap = cropCenterSquare(attachment.getUri(), size);
if (bitmap != null && "image/gif".equals(attachment.getMime())) { if (bitmap != null && "image/gif".equals(mime)) {
Bitmap withGifOverlay = bitmap.copy(Bitmap.Config.ARGB_8888, true); Bitmap withGifOverlay = bitmap.copy(Bitmap.Config.ARGB_8888, true);
drawOverlay(withGifOverlay, paintOverlayBlack(withGifOverlay) ? R.drawable.play_gif_black : R.drawable.play_gif_white, 1.0f); drawOverlay(withGifOverlay, paintOverlayBlack(withGifOverlay) ? R.drawable.play_gif_black : R.drawable.play_gif_white, 1.0f);
bitmap.recycle(); bitmap.recycle();
@ -936,12 +940,7 @@ public class FileBackend {
private Bitmap getPdfDocumentPreview(final File file, final int size) { private Bitmap getPdfDocumentPreview(final File file, final int size) {
try { try {
final ParcelFileDescriptor fileDescriptor = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY); final ParcelFileDescriptor fileDescriptor = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
final PdfRenderer pdfRenderer = new PdfRenderer(fileDescriptor); final Bitmap rendered = renderPdfDocument(fileDescriptor, size, true);
final PdfRenderer.Page page = pdfRenderer.openPage(0);
Dimensions dimensions = scalePdfDimensions(new Dimensions(page.getHeight(), page.getWidth()));
final Bitmap rendered = Bitmap.createBitmap(dimensions.width, dimensions.height, Bitmap.Config.ARGB_8888);
rendered.eraseColor(0xffffffff);
page.render(rendered, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
drawOverlay(rendered, paintOverlayBlackPdf(rendered) ? R.drawable.open_pdf_black : R.drawable.open_pdf_white, 0.75f); drawOverlay(rendered, paintOverlayBlackPdf(rendered) ? R.drawable.open_pdf_black : R.drawable.open_pdf_white, 0.75f);
return rendered; return rendered;
} catch (IOException e) { } catch (IOException e) {
@ -952,6 +951,34 @@ public class FileBackend {
} }
} }
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private Bitmap cropCenterSquarePdf(final Uri uri, final int size) {
try {
ParcelFileDescriptor fileDescriptor = mXmppConnectionService.getContentResolver().openFileDescriptor(uri, "r");
final Bitmap bitmap = renderPdfDocument(fileDescriptor, size, false);
return cropCenterSquare(bitmap, size);
} catch (Exception e) {
final Bitmap placeholder = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
placeholder.eraseColor(0xff000000);
return placeholder;
}
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private Bitmap renderPdfDocument(ParcelFileDescriptor fileDescriptor, int targetSize, boolean fit) throws IOException {
final PdfRenderer pdfRenderer = new PdfRenderer(fileDescriptor);
final PdfRenderer.Page page = pdfRenderer.openPage(0);
final Dimensions dimensions = scalePdfDimensions(new Dimensions(page.getHeight(), page.getWidth()), targetSize, fit);
final Bitmap rendered = Bitmap.createBitmap(dimensions.width, dimensions.height, Bitmap.Config.ARGB_8888);
rendered.eraseColor(0xffffffff);
page.render(rendered, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
page.close();
pdfRenderer.close();
fileDescriptor.close();
return rendered;
}
public Uri getTakePhotoUri() { public Uri getTakePhotoUri() {
File file; File file;
if (Config.ONLY_INTERNAL_STORAGE) { if (Config.ONLY_INTERNAL_STORAGE) {
@ -1339,8 +1366,12 @@ public class FileBackend {
private Dimensions scalePdfDimensions(Dimensions in) { private Dimensions scalePdfDimensions(Dimensions in) {
final DisplayMetrics displayMetrics = mXmppConnectionService.getResources().getDisplayMetrics(); final DisplayMetrics displayMetrics = mXmppConnectionService.getResources().getDisplayMetrics();
final int target = (int) (displayMetrics.density * 288); final int target = (int) (displayMetrics.density * 288);
return scalePdfDimensions(in, target, true);
}
private static Dimensions scalePdfDimensions(final Dimensions in, final int target, final boolean fit) {
final int w, h; final int w, h;
if (in.width <= in.height) { if (fit == (in.width <= in.height)) {
w = Math.max((int) (in.width / ((double) in.height / target)), 1); w = Math.max((int) (in.width / ((double) in.height / target)), 1);
h = target; h = target;
} else { } else {

View file

@ -44,6 +44,7 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
import eu.siacs.conversations.Config; import eu.siacs.conversations.Config;
import eu.siacs.conversations.utils.Compatibility;
import eu.siacs.conversations.utils.MimeUtils; import eu.siacs.conversations.utils.MimeUtils;
public class Attachment implements Parcelable { public class Attachment implements Parcelable {
@ -164,7 +165,13 @@ public class Attachment implements Parcelable {
} }
public boolean renderThumbnail() { public boolean renderThumbnail() {
return type == Type.IMAGE || (type == Type.FILE && mime != null && (mime.startsWith("video/") || mime.startsWith("image/"))); return type == Type.IMAGE || (type == Type.FILE && mime != null && renderFileThumbnail(mime));
}
private static boolean renderFileThumbnail(final String mime) {
return mime.startsWith("video/")
|| mime.startsWith("image/")
|| (Compatibility.runsTwentyOne() && "application/pdf".equals(mime));
} }
public Uri getUri() { public Uri getUri() {