How to convert Image to PDF?
Asked Answered
N

6

21

I am developing an application where I need to convert an Image to PDF. I tried something, but the issue is, Image size in that PDF is very very small. I need solution to fix this. Also I am looking for converting multiple Images into single PDF document. I will post the code which I tried.

    public void convertPDF(byte[] path)
{
 String FILE = "mnt/sdcard/FirstPdf.pdf";
    Document document=new Document();
    try {
        PdfWriter.getInstance(document, new FileOutputStream(FILE));
        document.open();

        try {
            image=Image.getInstance(path);
            document.add(new Paragraph("My Heading"));
            document.add(image);
            document.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    } catch (DocumentException e) {
        e.printStackTrace();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
}

When I convert Bitmap to Byte array, I am compressing the image and I guess, that's the reason. Without compressing the image, I am unable to convert Bitmap to Byte Array.

 ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bmp.compress(Bitmap.CompressFormat.PNG,100,stream);
        byte[] byteArray=stream.toByteArray();
        convertPDF(byteArray);

Is there any solution for this?

UPDATED

Here I have implemented the answer which suggested by @Burak Cakir in the answer. But now I am getting larger image in PDF. For better understanding, Please find the images below. enter image description here

The actually Image is enter image description here

Newbill answered 30/3, 2016 at 9:55 Comment(3)
Possible duplicate of Convert image to PDF in AndroidFiction
you can use itext library for this. here is an example of this. concretepage.com/itext/add-image-in-pdf-using-itext-in-javaMicrocline
I tried that. I implemented that code here. My problem is, Image is very small in PDF.Newbill
G
25

I would suggest you to use iText pdf library. Here is the gradle dependency:

implementation 'com.itextpdf:itextg:5.5.10'

 Document document = new Document();

 String directoryPath = android.os.Environment.getExternalStorageDirectory().toString();

 PdfWriter.getInstance(document, new FileOutputStream(directoryPath + "/example.pdf")); //  Change pdf's name.

 document.open();

 Image image = Image.getInstance(directoryPath + "/" + "example.jpg");  // Change image's name and extension.

 float scaler = ((document.getPageSize().getWidth() - document.leftMargin()
               - document.rightMargin() - 0) / image.getWidth()) * 100; // 0 means you have no indentation. If you have any, change it.
 image.scalePercent(scaler);
 image.setAlignment(Image.ALIGN_CENTER | Image.ALIGN_TOP); 

 document.add(image);
 document.close();
Gaucho answered 30/3, 2016 at 10:14 Comment(12)
I tried the code. Partially working, now Image is too big. Please find the updated question. I have posted few imagesNewbill
But, it varies from picture to picture. If I choose the image from camera, alignment is not proper. If I choose different image with different quality, again alignment differs. How can I dynamically fix this?Newbill
I dont know why it makes any difference from image to another image. Anyway, you can fix it by using setAlignment method. Updated again, check the answer pls.Gaucho
Hi @Baruk ,very useful answer, but i pass a above 4mb picture but get .58mb pdf .i want that pdf must be above 4mb .is there any solution?Airs
Hi @Suman, as far as i know, there is no method to change the pdf size. If you use the code lines above, there is scale part that scales the picture that's why the pdf size is much less than the picture size. So if you remove it, pdf has bigger size. But i'm not sure how it looks like.Gaucho
ok thank you @Baruk , can you confirm me one think that..when i create pdf from image then image quality decreased or not?Airs
@Suman, when you scale an Image object in iText, you don't lose any information: the number of pixels remains the same. Whereas PDF doesn't have a resolution, the images inside a PDF do. When you the image scale down (that is: you put the same number of pixels on a smaller canvas), the resolution increases; when you scale up, the resolution decreases. So quality ll be the same, the resolution is up to image size and document page size.Gaucho
Just so you know, it's now implementation 'com.itextpdf:itextpdf:5.5.13'Corbeil
hello, is this library can convert multiple images to single PDF file ?Decor
I haven't tried multiple images version before but if you change the above code correctly, i don't see any specific reason not to work.Gaucho
Hello, I've tried this code, It is working fine if I choose an Image from my Gallary, But very worst if I have captured an Image from my Camera. The Image get blured and cant read even a single text from that Image.Judon
It has been 4 years since I wrote this answer. I'm not sure if this library still works well today. I don't think this answer will blur the image. I suggest you take a look at the code you got the image from the gallery. Or you can check it like this, after getting the image from the gallery, set an image to ImageView and Pdf separately. If the results are different, you can give some specific details.Gaucho
G
19

Download source code from here (Convert Image to pdf in android programmatically)

MainActivity.java:

package com.deepshikha.convertbitmap;

import android.Manifest;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.pdf.PdfDocument;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    public static final int GALLERY_PICTURE = 1;
    Button btn_select, btn_convert;
    ImageView iv_image;
    boolean boolean_permission;
    boolean boolean_save;
    Bitmap bitmap;
    public static final int REQUEST_PERMISSIONS = 1;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
        listener();
        fn_permission();
    }

    private void init() {
        btn_select = (Button) findViewById(R.id.btn_select);
        btn_convert = (Button) findViewById(R.id.btn_convert);
        iv_image = (ImageView) findViewById(R.id.iv_image);
    }

    private void listener() {
        btn_select.setOnClickListener(this);
        btn_convert.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btn_select:
                Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(intent, GALLERY_PICTURE);
                break;

            case R.id.btn_convert:
                if (boolean_save){

                    Intent intent1=new Intent(getApplicationContext(),PDFViewActivity.class);
                    startActivity(intent1);

                }else {
                    createPdf();
                }
                break;


        }
    }

    private void createPdf(){
        WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        DisplayMetrics displaymetrics = new DisplayMetrics();
        this.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
        float hight = displaymetrics.heightPixels ;
        float width = displaymetrics.widthPixels ;

        int convertHighet = (int) hight, convertWidth = (int) width;

//        Resources mResources = getResources();
//        Bitmap bitmap = BitmapFactory.decodeResource(mResources, R.drawable.screenshot);

        PdfDocument document = new PdfDocument();
        PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(bitmap.getWidth(), bitmap.getHeight(), 1).create();
        PdfDocument.Page page = document.startPage(pageInfo);

        Canvas canvas = page.getCanvas();


        Paint paint = new Paint();
        paint.setColor(Color.parseColor("#ffffff"));
        canvas.drawPaint(paint);



        bitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth(), bitmap.getHeight(), true);

        paint.setColor(Color.BLUE);
        canvas.drawBitmap(bitmap, 0, 0 , null);
        document.finishPage(page);


        // write the document content
        String targetPdf = "/sdcard/test.pdf";
        File filePath = new File(targetPdf);
        try {
            document.writeTo(new FileOutputStream(filePath));
            btn_convert.setText("Check PDF");
            boolean_save=true;
        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(this, "Something wrong: " + e.toString(), Toast.LENGTH_LONG).show();
        }

        // close the document
        document.close();
    }



    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == GALLERY_PICTURE && resultCode == RESULT_OK) {

            if (resultCode == RESULT_OK) {
                Uri selectedImage = data.getData();
                String[] filePathColumn = {MediaStore.Images.Media.DATA};

                Cursor cursor = getContentResolver().query(
                        selectedImage, filePathColumn, null, null, null);
                cursor.moveToFirst();

                int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                String filePath = cursor.getString(columnIndex);
                cursor.close();


                bitmap = BitmapFactory.decodeFile(filePath);
                iv_image.setImageBitmap(bitmap);


                btn_convert.setClickable(true);
            }
        }
    }

    private void fn_permission() {
        if ((ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)||
                (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) {

            if ((ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, android.Manifest.permission.READ_EXTERNAL_STORAGE))) {
            } else {
                ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE},
                        REQUEST_PERMISSIONS);

            }

            if ((ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE))) {
            } else {
                ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                        REQUEST_PERMISSIONS);

            }
        } else {
            boolean_permission = true;


        }
    }
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_PERMISSIONS) {

            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                boolean_permission = true;


            } else {
                Toast.makeText(getApplicationContext(), "Please allow the permission", Toast.LENGTH_LONG).show();

            }
        }
    }


}

Thanks!

Godship answered 28/6, 2017 at 16:2 Comment(3)
Thanks for the code , I tried and it works ! but the quality of the image is poor.. I use the camera intent to get the bitmap instead of choosing the file. For the quality it may be because you resize the bitmap when you do that bitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth(), bitmap.getHeight(), true);Grapnel
Eventually, this code worked perfectly for me. I had an image which was created using a scrollView, Since it was a tablet, it had over 3000 * 10000 resolution. The accepted answer only printed out one portion of the image, but this solution printed out everything.Febrifacient
Could you please update above source code link , it is not accessible or could suggest any proper tutorial for creating image to pdf converter app for androidMalayalam
M
17

You can convert a JPG to a PDF by targeting a minimum SDK of 19 (KitKat 4.4) and using Google's PdfDocument API ( https://developer.android.com/reference/android/graphics/pdf/PdfDocument ), as shown below in Kotlin:

    // Load JPG file into bitmap
    val f: File = myJPGFile
    val bitmap: Bitmap  = BitmapFactory.decodeFile(f.absolutePath)

    // Create a PdfDocument with a page of the same size as the image
    val document: PdfDocument = PdfDocument()
    val pageInfo: PdfDocument.PageInfo  = PdfDocument.PageInfo.Builder(bitmap.width, bitmap.height, 1).create()
    val page: PdfDocument.Page  = document.startPage(pageInfo)

    // Draw the bitmap onto the page
    val canvas: Canvas = page.canvas
    canvas.drawBitmap(bitmap, 0f, 0f, null)
    document.finishPage(page)

    // Write the PDF file to a file
    val directoryPath: String  = android.os.Environment.getExternalStorageDirectory().toString()
    document.writeTo( FileOutputStream(directoryPath + "/example.pdf"))
    document.close()
Miles answered 1/5, 2019 at 5:11 Comment(0)
E
6

Just pass context and list of file It will create a PDF file in cache dir Add your own logic to share/open PDF Works fast and reliable method

  • No library needed (Uses android internal android.graphics.pdf.PdfDocument classes)
  • Works in background, Doesn''t freeze UI
  • No need to declare and grant storage permission :)
private static void createPdf(Context context,ArrayList<File> data){
    File pdfFile = new File(context.getExternalCacheDir().getAbsolutePath() + File.separator + "TemperoryPDF_"+System.currentTimeMillis()+".pdf");
    Toast.makeText(context, "Creating PDF,Please wait..", Toast.LENGTH_SHORT).show();
    new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(Void... voids) {
            PdfDocument document = new PdfDocument();
            try {
                for(File item:data) {
                    Bitmap bitmap = BitmapFactory.decodeFile(item.getAbsolutePath());
                    PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(bitmap.getWidth(), bitmap.getHeight(), 1).create();
                    PdfDocument.Page page = document.startPage(pageInfo);
                    Canvas canvas = page.getCanvas();
                    Paint paint = new Paint();
                    paint.setColor(Color.parseColor("#ffffff"));
                    canvas.drawPaint(paint);
                    canvas.drawBitmap(bitmap, 0, 0, null);
                    document.finishPage(page);
                }
                document.writeTo(new FileOutputStream(pdfFile));
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                document.close();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void unused) {
            super.onPostExecute(unused);
            if(pdfFile.exists() && pdfFile.length()>0) {
                FileUtil.openFile(context, pdfFile.getAbsolutePath()); // See: https://gist.github.com/omkar-tenkale/34d3aa1966653e6949d1ddaee1ba3355
            }else {
                Toast.makeText(context, "Something went wrong creating the PDF :(", Toast.LENGTH_SHORT).show();
            }
        }
    }.execute();

}
Ethno answered 23/7, 2021 at 21:13 Comment(2)
tested on android 12, worksEthno
many thanks, exactly what I looking for :)Roselani
K
1

Add library in gradle

implementation 'com.itextpdf:itextg:5.5.10'

Create folder path - it will create pdf from all images of folder

File folderPath = new File(Environment.getExternalStorageDirectory() + "/YourImagesFolder");

File[] imageList = folderPath .listFiles();
ArrayList<File> imagesArrayList = new ArrayList<>();
for (File absolutePath : imageList) {
          imagesArrayList.add(absolutePath);
}
new CreatePdfTask(context, imagesArrayList).execute();

AsyncTask

 public class CreatePdfTask extends AsyncTask<String, Integer, File> {
    Context context;
    ArrayList<File> files;
    ProgressDialog progressDialog;

    public CreatePdfTask(Context context2, ArrayList<File> arrayList) {
        context = context2;
        files = arrayList;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        progressDialog = new ProgressDialog(context);
        progressDialog.setTitle("Please wait...");
        progressDialog.setMessage("Creating pdf...");
        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progressDialog.setIndeterminate(false);
        progressDialog.setMax(100);
        progressDialog.setCancelable(true);
        progressDialog.show();
    }

    @Override
    protected File doInBackground(String... strings) {
        File outputMediaFile = Constant.getPdfPath();//path in which you want to save pdf

        Document document = new Document(PageSize.A4, 38.0f, 38.0f, 50.0f, 38.0f);
        try {
            PdfWriter.getInstance(document, new FileOutputStream(outputMediaFile));
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return null;
        }
        document.open();

        int i = 0;
        while (true) {
            if (i < this.files.size()) {
                try {
                    Image image = Image.getInstance(files.get(i).getAbsolutePath());

                    float scaler = ((document.getPageSize().getWidth() - document.leftMargin()
                            - document.rightMargin() - 0) / image.getWidth()) * 100; // 0 means you have no indentation. If you have any, change it.
                    image.scalePercent(scaler);
                    image.setAlignment(Image.ALIGN_CENTER | Image.ALIGN_TOP);
                    image.setAbsolutePosition((document.getPageSize().getWidth() - image.getScaledWidth()) / 2.0f,
                            (document.getPageSize().getHeight() - image.getScaledHeight()) / 2.0f);

                    document.add(image);
                    document.newPage();
                    publishProgress(i);
                    i++;
                } catch (BadElementException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (DocumentException e) {
                    e.printStackTrace();
                }
            } else {
                document.close();
                return outputMediaFile;
            }
        }
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        this.progressDialog.setProgress(((values[0] + 1) * 100) / this.files.size());
        StringBuilder sb = new StringBuilder();
        sb.append("Processing images (");
        sb.append(values[0] + 1);
        sb.append("/");
        sb.append(this.files.size());
        sb.append(")");
        progressDialog.setTitle(sb.toString());
    }

    @Override
    protected void onPostExecute(File file) {
        super.onPostExecute(file);
        progressDialog.dismiss();
        Toast.makeText(context, "Pdf store at " + file.getAbsolutePath(), Toast.LENGTH_SHORT).show();
    }
}
Kc answered 13/8, 2020 at 8:39 Comment(1)
You must make your app open source if you use this library according to their license!!!!Ethno
S
0

this is how I convert image into pdf very easy , you need to declare the user permission first in the manifest

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

then in your main activity, you must check for permission is granted or not if you don't know how to do it just search on youtube you will find a lot of videos about that topic, after that, I use this method to pic image that i want to convert into pdf from the gallery.

public void pickImage() {
    Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    startActivityForResult(intent,120);
}

After that I override the onActivityResult() method to retrieve the selected image .

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 120 && resultCode == RESULT_OK && data != null) {
        Uri selectedImageUri = data.getData();

        String[] filePath = {MediaStore.Images.Media.DATA};
        Cursor cursor =getContentResolver().query(selectedImageUri,filePath,null,null,null);
        cursor.moveToFirst();

        int columnIndex = cursor.getColumnIndex(filePath[0]);
        String myPath = cursor.getString(columnIndex);
        cursor.close();

        Bitmap bitmap = BitmapFactory.decodeFile(myPath);
        imageView.setImageBitmap(bitmap);

        PdfDocument pdfDocument = new PdfDocument();
        PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(bitmap.getWidth(),
                bitmap.getHeight(),1).create();
        PdfDocument.Page page = pdfDocument.startPage(pageInfo);

        Canvas canvas = page.getCanvas();
        Paint paint = new Paint();
        paint.setColor(Color.parseColor("#FFFFFF"));
        canvas.drawPaint(paint);

        bitmap=Bitmap.createScaledBitmap(bitmap,bitmap.getWidth(),bitmap.getHeight(),true);
        paint.setColor(Color.BLUE);
        canvas.drawBitmap(bitmap,0,0,null);

        pdfDocument.finishPage(page);

        //save the bitmap image
        File root = new File(Environment.getExternalStorageDirectory(),"PDF folder 12");
        if (!root.exists()){
            root.mkdir();
        }
        File file = new File(root,"picture.pdf");
        try {
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            pdfDocument.writeTo(fileOutputStream);
        }catch (Exception e){
            e.getStackTrace();
        }
        pdfDocument.close();
    }
}

don't forget the permission and ask the user to grant the permission

If you want to open pdf file automatically use this method after given the right path to the folder and pdf file name

 String path ="/sdcard/PDF folder 12/picture.pdf";
public void openPDF (){
    File pdfFile = new File(path);//File path
    if (pdfFile.exists()) //Checking if the file exists or not
    {
        Uri path = Uri.fromFile(pdfFile);
        Intent objIntent = new Intent(Intent.ACTION_VIEW);
        objIntent.setDataAndType(path, "application/pdf");
        objIntent.setFlags(Intent. FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(objIntent);//Starting the pdf viewer
    } else {

        Toast.makeText(GenerateQRActivity.this, "The file not exists! ", Toast.LENGTH_SHORT).show();

    }
}
Sabol answered 16/2, 2022 at 12:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.