33

I want to generate the image(thumbnail) from pdf file just like done by WhatsApp as shown below WhatsApp

I have tried

  1. PDFBox (https://github.com/TomRoush/PdfBox-Android)
  2. Tika (compile 'org.apache.tika:tika-parsers:1.11')
  3. AndroidPdfViewer (https://github.com/barteksc/AndroidPdfViewer)

and still unable to find a way to generate image from pdf.


PDFBox:

There is a github issue that deals with this problem (https://github.com/TomRoush/PdfBox-Android/issues/3) but this is still unresolved.

Note: I am successfully able to extract image from PDF using PDFBOX


AndroidPdfViewer:

Github issue (https://github.com/barteksc/AndroidPdfViewer/issues/49)

shanraisshan
  • 3,521
  • 2
  • 21
  • 44
  • Whatsapp does it server-side. – Mohamed Nuur Feb 14 '20 at 16:44
  • Hello @shanraisshan. I'm trying to achieve a similar functionality. Could you please share some sample code, how you achieve it? Or some link which could guide me for the same. Best Regards – Arjun Sep 02 '21 at 09:57

4 Answers4

38

Use PdfiumAndroid as mentioned by barteksc here.

Still working in 2021...

Sample Code for generating Pdf thumb

//PdfiumAndroid (https://github.com/barteksc/PdfiumAndroid)
//https://github.com/barteksc/AndroidPdfViewer/issues/49
void generateImageFromPdf(Uri pdfUri) {
    int pageNumber = 0;
    PdfiumCore pdfiumCore = new PdfiumCore(this);
    try {
        //http://www.programcreek.com/java-api-examples/index.php?api=android.os.ParcelFileDescriptor
        ParcelFileDescriptor fd = getContentResolver().openFileDescriptor(pdfUri, "r");
        PdfDocument pdfDocument = pdfiumCore.newDocument(fd);
        pdfiumCore.openPage(pdfDocument, pageNumber);
        int width = pdfiumCore.getPageWidthPoint(pdfDocument, pageNumber);
        int height = pdfiumCore.getPageHeightPoint(pdfDocument, pageNumber);
        Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        pdfiumCore.renderPageBitmap(pdfDocument, bmp, pageNumber, 0, 0, width, height);
        saveImage(bmp);
        pdfiumCore.closeDocument(pdfDocument); // important!
    } catch(Exception e) {
        //todo with exception
    }
}

public final static String FOLDER = Environment.getExternalStorageDirectory() + "/PDF";
private void saveImage(Bitmap bmp) {
    FileOutputStream out = null;
    try {
        File folder = new File(FOLDER);
        if(!folder.exists())
            folder.mkdirs();
        File file = new File(folder, "PDF.png");
        out = new FileOutputStream(file);
        bmp.compress(Bitmap.CompressFormat.PNG, 100, out); // bmp is your Bitmap instance
    } catch (Exception e) {
        //todo with exception
    } finally {
        try {
            if (out != null)
                out.close();
        } catch (Exception e) {
            //todo with exception
        }
    }
}

Update:

Include the library in the build.gradle

implementation 'com.github.barteksc:android-pdf-viewer:3.2.0-beta.1'

For generating Image of any PDF Page:

Call the method generateImageFromPdf(uri) by passing any PDF uri that is stored in your storage.

The method will generate the PDF.png in the PDF folder of your storage.

Sam Joshua
  • 310
  • 6
  • 17
  • 1
    You should really add some explanation as to why this code should work - you can also add comments in the code itself - in its current form, it does not provide any explanation which can help the rest of the community to understand what you did to solve/answer the question. – ishmaelMakitla Aug 08 '16 at 12:45
  • How can I get the "ParcelFileDescriptor fd" from Assets? – Ponomarenko Oleh Nov 10 '17 at 23:06
  • Hi, I not get error but the png is not create to my storage. and I think the code `ParcelFileDescriptor fd = getContentResolver().openFileDescriptor(pdfUri, "r");` is not working – Eggy Apr 09 '18 at 02:06
  • not working, should i save the bitmap, cannot i just set imageview with the generated bitmap? – Masterpiece Mas Icang Sep 20 '18 at 02:17
  • Not Working. When i set the bitmap to imageView it does not show anything. – Ashwini Jan 17 '20 at 10:45
  • This library increases my app size by 15MB. Is there any alternative available for just creating the thumbnail. – Nilesh Rathore May 31 '20 at 13:15
  • @NileshRathore have you found out any solution? If yes, can you please share I am also with the same. – bhaskar Jun 17 '21 at 10:46
6

Using Android PDFRenderer Component

with(context) {
    contentResolver.openFileDescriptor(uri, "r")?.use { parcelFileDescriptor ->
        val pdfRenderer = PdfRenderer(parcelFileDescriptor).openPage(0)
        val bitmap = Bitmap.createBitmap(pdfRenderer.width, pdfRenderer.height, Bitmap.Config.ARGB_8888)
        pdfRenderer.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY)
        pdfRenderer.close()      
    }
}
zen_of_kermit
  • 1,404
  • 2
  • 13
  • 19
Gagan Belgur
  • 61
  • 1
  • 2
1
val file = Constant.allMediaList[position]
val filename = Environment.getExternalStoragePublicDirectory(file)
if (file != null) {
    if (file.endsWith(".pdf")){
        val fd :ParcelFileDescriptor= ParcelFileDescriptor.open(filename,ParcelFileDescriptor.MODE_READ_WRITE)
        val pageNum: Int  = 0;
        val pdfiumCore: PdfiumCore  = PdfiumCore(mContext);
        try {
            val pdfDocument: PdfDocument = pdfiumCore.newDocument(fd);
            pdfiumCore.openPage(pdfDocument, pageNum);
            val width:  Int  = pdfiumCore.getPageWidthPoint(pdfDocument, pageNum);
            val height:  Int = pdfiumCore.getPageHeightPoint(pdfDocument, pageNum);

            // ARGB_8888 - best quality, high memory usage, higher possibility of OutOfMemoryError
            // RGB_565 - little worse quality, twice less memory usage
            val 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

            Glide.with(mContext)
                .load(bitmap).into(holder.thumbnail)

            pdfiumCore.closeDocument(pdfDocument); // important!
        } catch(ex: IOException) {
            ex.printStackTrace();
            Toast.makeText(mContext,"failed",Toast.LENGTH_LONG).show()
        }

    }
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
Pro kashan
  • 21
  • 1
  • 2
  • While this code may solve the question, [including an explanation](//meta.stackexchange.com/q/114762) of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please [edit] your answer to add explanations and give an indication of what limitations and assumptions apply. – Suraj Rao Nov 07 '20 at 08:09
  • Please don't post only code as answer, but also provide an explanation what your code does and how it solves the problem of the question. Answers with an explanation are usually more helpful and of better quality, and are more likely to attract upvotes. – Pouria Hemi Nov 07 '20 at 08:34
0
Bitmap myBitmap = generateImageFromPdf(FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".provider", Pdf_File.get(position).getAbsoluteFile()));
    holder.iv_icon.setImageBitmap(myBitmap);

}

Bitmap generateImageFromPdf(Uri pdfUri) {
    int pageNumber = 0;
    PdfiumCore pdfiumCore = new PdfiumCore(context);
    Bitmap bmp = null;
    try {
        //http://www.programcreek.com/java-api-examples/index.php?api=android.os.ParcelFileDescriptor
        ParcelFileDescriptor fd = context.getContentResolver().openFileDescriptor(pdfUri, "r");
        PdfDocument pdfDocument = pdfiumCore.newDocument(fd);
        pdfiumCore.openPage(pdfDocument, pageNumber);
        int width = pdfiumCore.getPageWidthPoint(pdfDocument, pageNumber);
        int height = pdfiumCore.getPageHeightPoint(pdfDocument, pageNumber);
        Log.e("Width_height", "" + width + " " + height);
        bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        pdfiumCore.renderPageBitmap(pdfDocument, bmp, pageNumber, 0, 0, width, height);
        pdfiumCore.closeDocument(pdfDocument);
    } catch (Exception e) {
        //todo with exception
    }
    return bmp;
}