Anish Kumar
Anish Kumar

Reputation: 488

How to convert Image to PDF?

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

Upvotes: 22

Views: 59676

Answers (6)

jenos kon
jenos kon

Reputation: 564

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();

    }
}

Upvotes: 0

Omkar T
Omkar T

Reputation: 883

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();

}

Upvotes: 6

jay patoliya
jay patoliya

Reputation: 761

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();
    }
}

Upvotes: 1

Burak Cakir
Burak Cakir

Reputation: 928

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();

Upvotes: 25

Anthony.
Anthony.

Reputation: 771

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()

Upvotes: 17

Deepshikha Puri
Deepshikha Puri

Reputation: 2094

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!

Upvotes: 19

Related Questions