Как конвертировать изображение в PDF?
Я разрабатываю приложение, в котором мне нужно конвертировать изображение в PDF. Я пытался что-то, но проблема в том, что размер изображения в этом PDF очень маленький. Мне нужно решение, чтобы это исправить. Также я ищу для преобразования нескольких изображений в один документ PDF. Я выложу код, который я попробовал.
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();
}
}
Когда я конвертирую растровое изображение в байтовый массив, я сжимаю изображение и думаю, в этом причина. Без сжатия изображения я не могу преобразовать растровое изображение в байтовый массив.
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG,100,stream);
byte[] byteArray=stream.toByteArray();
convertPDF(byteArray);
Есть ли решение для этого?
ОБНОВЛЕНО
Здесь я реализовал ответ, предложенный @Burak Cakir в ответе. Но теперь я получаю увеличенное изображение в PDF. Для лучшего понимания, пожалуйста, найдите изображения ниже.
7 ответов
Я бы предложил вам использовать iText
Библиотека PDF. Здесь gradle
зависимость:
compile 'com.itextpdf:itextg:5.5.10'
Для android-studio 3.0 используйте:
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();
Скачать исходный код отсюда ( Конвертировать изображение в PDF в Android программно)
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();
}
}
}
}
Спасибо!
Вы можете конвертировать JPG в PDF, настроив минимальный SDK 19 (KitKat 4.4) и используя Google PdfDocument API ( https://developer.android.com/reference/android/graphics/pdf/PdfDocument), как показано ниже в Котлин:
// 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()
Просто передайте контекст и список файлов. Он создаст файл PDF в каталоге кеша. Добавьте свою логику для совместного использования / открытия PDF. Работает быстро и надежно.
- Библиотека не требуется (используются внутренние классы android.graphics.pdf.PdfDocument для Android)
- Работает в фоновом режиме, интерфейс не зависает
- Не нужно объявлять и предоставлять разрешение на хранение :)
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);
bitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth(), bitmap.getHeight(), true);
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();
}
Добавить библиотеку в Gradle
implementation 'com.itextpdf:itextg:5.5.10'
Создать путь к папке - он будет создавать pdf из всех изображений папки
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();
}
}
С помощью этого кода вы можете конвертировать изображение в PDF-файл.
import java.io.*;
import com.lowagie.text.*;
import com.lowagie.text.pdf.*;
public class imagesPDF
{
public static void main(String arg[])throws Exception
{
Document document=new Document();
PdfWriter.getInstance(document,new FileOutputStream("YourPDFHere.pdf"));
document.open();
Image image = Image.getInstance ("yourImageHere.jpg");
document.add(new Paragraph("Your Heading for the Image Goes Here"));
document.add(image);
document.close();
}
}
Для изображений в PDF могут быть доступны библиотеки, такие как iText, droidtext, так что вы можете использовать их.
вот как я очень легко конвертирую изображение в pdf, вам нужно сначала объявить разрешение пользователя в манифесте
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
затем в вашей основной деятельности вы должны проверить, предоставлено ли разрешение или нет, если вы не знаете, как это сделать, просто выполните поиск на YouTube, вы найдете много видео на эту тему, после этого я использую этот метод для изображения изображения что я хочу преобразовать в pdf из галереи.
public void pickImage() {
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent,120);
}
После этого я переопределяю метод onActivityResult() для получения выбранного изображения.
@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();
}
}
не забудьте разрешение и попросите пользователя предоставить разрешение
Если вы хотите автоматически открыть файл PDF, используйте этот метод после указания правильного пути к папке и имени файла PDF.
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();
}
}